; Disassembly of bios7800.bin
; Disassembled Sun Mar 08 20:30:38 1998
; Using DiStella v2.0
;
; Comments added by Keith Henrickson <flipper@phin.com>
; Further commented by Daniel Boris <dboris@home.com>
; They may be wrong. Use at your own risk.  Modification suggested
; for bypassing authentication scheme is at this date untested.
;
; Command Line: E:\DISTELLA\DISTELLA.EXE -cbios7800.cfg bios7800.bin 
;
; bios7800.cfg contents:
;
;      ORG F000
;      CODE F000 F003
;      CODE F400 F52D
;      CODE F636 F6D8
;      CODE F6E1 F761
;      CODE F76A F838
;      CODE F8E7 F91C
;      CODE F9EE FBBD

; 7800 system

INPTCTRL = $01

; TIA

VSYNC   =  $00
VBLANK  =  $01
WSYNC   =  $02
RSYNC   =  $03
COLUP0  =  $06
COLUPF  =  $08
COLUBK  =  $09
PF2     =  $0F
RESP1   =  $11
GRP0    =  $1B
GRP1    =  $1C

;Maria

BACKGRND=  $20
POC1    =  $21
POC2    =  $22
POC3    =  $23
WSYNC   =  $24
P1C1  =  $25
P1C2  =  $26
P1C3  =  $27
MSTAT  =  $28
DPPH   =  $2C
DPPL   =  $30
CTRL   =  $3C

; Addresses

LF409   =   $F409
LF412   =   $F412
LF41B   =   $F41B
LF460   =   $F460
LF500   =   $F500
LF639   =   $F639
LF655   =   $F655
LF659   =   $F659
LF662   =   $F662
LF66E   =   $F66E
LF672   =   $F672
LF679   =   $F679
LF67C   =   $F67C
LF68C   =   $F68C
LF68F   =   $F68F
LF690   =   $F690
LF69A   =   $F69A
LF69F   =   $F69F
LF6A8   =   $F6A8
LF6AD   =   $F6AD
LF6B9   =   $F6B9
LF6C2   =   $F6C2
LF700   =   $F700
LF800   =   $F800
LF901   =   $F901
LFA84   =   $FA84

       ORG $F000

LF000: PHA                ; This is the NMI routine.
       JMP($00F4)         ; RAM NMI vector is at $00F4.


; this code is designed to be executed while stored in ram at 2300.
LF400: JMP    $26C2       ; Enter 2600 mode.
LF403: JMP    $26C2       ; Enter 2600 mode.

LF406: LDA    #$16        ; ($2306)
       STA    INPTCTRL    ; Switch in Cart
LF40A: LDY    #$FF        ;
       LDX    #$7F        ;
LF40E: LDA    LFE00,X     ;
       CMP    LFD80,Y     ;
       BNE    LF400       ; Switch to 2600 mode
       DEY                ;
       DEX                ;
       BPL    LF40E       ; Compares FE7F with FE7F two ways??
       LDA    LFFFC       ;
       AND    LFFFD       ;
       CMP    #$FF        ;
       BEQ    LF400       ; If RESET vector is FFFF, then go 2600.
       LDA    LFFFC       ;
       ORA    LFFFD       ;
       BEQ    LF400       ; If RESET vector is 0000, then go 2600.
       LDA    LFFF8       ; "Region verification"
       ORA    #$FE        ;
       CMP    #$FF        ;
       BNE    LF403       ; If low-bit of FFF8=0, then go 2600.
       LDA    LFFF8       ;
       EOR    #$F0        ; Invert high nibble
       AND    #$F0        ; Extract high nibble
       BNE    LF403       ; If high nibble was not F, then go 2600.
       LDA    LFFF9       ;
       AND    #$0B        ; Apply mask 00001011
       CMP    #$03        ; Low two bits must be set. Bit 2 can. Bit 3 not.
       BNE    LF403       ; If low nibble FFF9 was not 3 or 7, go 2600.
       LDA    LFFF9       ;
       AND    #$F0        ; Extract ROM start
       STA    $EE         ; Store it 
       STA    $2406       ; Store it a couple of places for auth. (whocares)
       CMP    #$40        ;
       BCC    LF403       ; If ROM start < than 4, then go 2600
       SBC    #$01        ; Subtract 1.
       CMP    LFFFD       ; High byte of reset vector
       BCS    LF403       ; If high-byte of start is >=, go 2600
       JSR    $2536       ; Start the authentication process.

       LDA    #$00
       STA    $F0     
       JSR    $241B   
       LDA    #$16    
       STA    INPTCTRL  
       LDX    #$00    
       TXA            
LF46D: STA    $1800,X 
       DEX            
       BNE    LF46D   
       PHA            
       LDY    #$7F    
LF476: LDA    LFF00,Y 
       STA    $1800,Y 
       DEY            
       CPY    #$F8    
       BNE    LF476   
       LDA    #$2E    
       STA    $2409   
       LDA    #$24    
       STA    $240A   
LF48B: JSR    $241B   
       PLA            
       JSR    $23FF   
       PHA            
       INC    $2406   
       LDA    $2406   
       CMP    #$FF    
       BNE    LF48B   
       JSR    $241B   
       JSR    $2412   
       JSR    $2412   
       LDA    #$36    
       STA    $2409   
       LDA    #$24    
       STA    $240A   
       DEC    $2406   
LF4B3: JSR    $241B   
       PLA            
       JSR    $23FF   
       PHA            
       DEC    $2406   
       LDA    $2406   
       CMP    $EE     
       BCS    LF4B3   
       LDA    #$60    
       STA    CTRL   
       LDX    #$77    
LF4CB: LDA    $1800,X 
       EOR    $1850,X 
       EOR    $1888,X 
       STA    $1A00,X 
       DEX            
       BPL    LF4CB   
       LDA    $1A00   
       AND    #$07    
       STA    $1A00   
       LDA    #$00    
       LDX    #$04    
       STA    $1A00,X 
       STA    $2000,X 
       LDX    #$77         ; That was a lot, but we end up here, comparing
LF4EE: LDA    $2000,X      ; two parts of memory.  If they match, then
       CMP    $1A00,X      ; go to 7800 mode....
       BNE    LF4FC        ; otherwise go to 2600 mode.
       DEX                 ; NOP out above branch to allow user-written
       BPL    LF4EE        ; carts to run -- I think.
       JMP    $26B9        ; 7800 mode init
LF4FC: JMP    $26C2        ; 2600 mode init.

       LDX    #$00         ; more authentication stuff all the way through
LF501: ADC    $1800,X 
       ADC    LFF00,X 
       TAY            
       LDA    $2DD5,Y 
       STA    $1800,X 
       INX            
       BNE    LF501   
       RTS            

       LDX    #$00    
LF514: ROL    $1800,X 
       INX            
       BNE    LF514   
       RTS            

       PHP            
       DEC    $F0     
       BPL    LF52C   
       LDA    #$02    
       STA    INPTCTRL  
LF524: LDA    $F0     
       BMI    LF524   
       LDA    #$16    
       STA    INPTCTRL  
LF52C: PLP            
       RTS            

LF52E: .byte $C7,$65,$AB,$CA,$EE,$F7,$83,$09
LF536: .byte $E1,$D0,$92,$67,$62,$B6,$72,$55,$8E,$91,$DC,$C5,$81,$BE,$78,$20
       .byte $59,$B7,$E6,$3D,$06,$45,$AF,$C8,$08,$31,$38,$D1,$FB,$73,$84,$A9
       .byte $17,$FC,$34,$87,$A3,$94,$FA,$90,$B8,$ED,$CE,$3B,$5B,$0A,$43,$D9
       .byte $F3,$53,$82,$B3,$0D,$6D,$5A,$60,$9D,$51,$A7,$B9
LF572: .byte $11,$10,$BC,$E4,$7F,$80,$41,$E7,$E3
LF57B: .byte $F6,$56,$26,$35,$EC,$D6,$DF,$0C,$7F,$F4,$9E,$AC,$52,$46,$EF,$CF
       .byte $BF,$A2,$3F,$A4,$13,$15,$97,$4A,$1C,$B0,$42,$8C,$B1,$05,$58,$80
       .byte $18,$77,$2B,$02,$3E,$A8,$49,$1A,$6A
LF5A4: .byte $CB,$6E,$0B,$8A,$EB,$F1,$4F,$14,$79,$8B,$D8,$9F,$9B,$57,$19,$F8
       .byte $2A,$2D,$76,$0E,$E8,$2E,$4B,$F9,$07,$03,$DE,$93,$16,$7E,$D4,$E5
       .byte $B2,$F0,$7D,$7A,$DA,$D2,$A1,$CC,$1D,$E0,$5E,$23,$A0,$95,$22,$1E
       .byte $36,$85,$FE,$1F,$39
LF5D9: .byte $AA,$89,$96,$AD,$0F,$2F,$C0,$47
LF5E1: .byte $27,$5D,$24,$EA,$C3,$A5,$F5,$21,$5F,$1B,$40,$8F,$AE,$74,$25,$DD
       .byte $C1,$7C,$CD,$A6,$70,$D7,$33,$7B,$2C,$75,$BB,$86,$99,$BD,$54
LF600: .byte $9A,$6C,$63,$32,$48,$4C,$8D,$BA
LF608: .byte $5C,$61,$C4,$4E,$29,$37,$12,$C6,$98,$9C,$D5,$69,$6B,$E2,$04,$4D
       .byte $E9,$C2,$88,$3A,$DB,$64,$01,$44,$6F,$B5,$F2,$30,$28,$FD,$50,$71
       .byte $3C,$B4,$66,$68,$C9,$D3,$CA,$83,$C7,$AB,$F7,$65,$09,$EE

       LDX    #$77      ;($2536)
       STX    $E4     
       STX    $E5     
LF63C: LDA    LFF80,X   ;Read Key
       STA    $1901,X   ;Store it
       STA    $2000,X   ;Store it again
       DEX              ;next byte of key
       BPL    LF63C     ;Continue

       LDA    #$02      ;
       STA    INPTCTRL  ;Disable cart 
       JSR    LFB84     ;Init display
       JSR    $257B   
       DEC    $F2     
       LDX    #$77    
       STX    $E4     
LF658: LDA    LFED5,X 
       STA    $1901,X 
       DEX            
       BPL    LF658   
       LDA    $E1     
       STA    $E3     
       JSR    $25E1   
       DEC    $F2     
LF66A: LDA    $E0     
       STA    $2572   
       LDX    #$77    
LF671: LDA    $1800,X 
LF674: STA    $2000,X 
       DEX            
       BPL    LF671   
       RTS            
    
       JSR    $2639   ;($257B)
       LDY    $E5     
       INY            
LF681: STY    $E1     
       TYA            
       CLC            
       ADC    $E2     
       PHA            
LF688: TAX            
       LDA    #$00    
       STA    $2671   
LF68E: STA    $1800,X 
       DEX            
LF692: BNE    LF68E   
       STA    $1800   
LF697: INY            
       STY    $266E   
       STY    $2674   
       STY    $267C   
       STY    $2681   
       LDX    #$00    
LF6A6: DEC    $266E   
LF6A9: DEC    $2674   
LF6AC: DEC    $267C   
       DEC    $2681   
       DEC    $E1     
       BMI    LF6D1   
LF6B6: LDY    $E1     
       LDA    $2000,Y 
       AND    $25D9,X 
       BEQ    LF6C9   
       LDA    $2662,X 
       STA    $2672   
       JSR    $266A   
LF6C9: INX            
       CPX    #$08    
       BMI    LF6B6   
       JMP    $25A4   
LF6D1: PLA            
       STA    $E1     
       LDA    #$01    
       STA    $E0     
       RTS            

LF6D9: .byte $01,$02,$04,$08,$10,$20,$40,$80

       JSR    $2639
       LDA    $E3     
       SEC            
       SBC    $E4     
       STA    $E0     
       STA    $E1     
       LDX    #$00    
       STX    $1800   
       STX    $268F   
       STX    $26AC   
       DEX            
       STX    $26A9   
       STX    $268C   
       STX    $2692   
       STX    $269A   
       STX    $269F   
       LDX    #$07    
       INC    $26A9   
       INC    $268C   
       INC    $2692   
       INC    $269A   
       INC    $269F   
       DEC    $E1     
       BMI    LF734   
LF71D: LDA    $2662,X 
       STA    $2690   
       STA    $26AD   
       JSR    $26A6   
       BCC    LF72E   
       JSR    $2688   
LF72E: DEX            
       BPL    LF71D   
       JMP    $2608   
LF734: LDA    $E3     
       STA    $E1     
       RTS            

       LDX    $E4   ;($2639)
       INX            
       STX    $E2     
       LDY    #$00    
       STY    $1900   
LF743: LDA    $2662,Y 
       STA    $2655   
       INY            
       LDA    $2662,Y 
       STA    $2659   
       LDX    $E2     
       CLC            
LF753: LDA    $1900,X 
       ROL    A       
       STA    $1900,X 
       DEX            
       BPL    LF753   
       CPY    #$07    
       BMI    LF743   
       RTS            

LF762: .byte $19,$1A,$1B,$1C,$1D,$1E,$1F,$21

       LDY    $E2
       CLC            
LF76D: LDA    $1800,Y 
       ADC    $1900,Y 
       STA    $1800,Y 
       DEY            
       BPL    LF76D   
       BCC    LF787   
       LDA    $1700,Y 
       ADC    #$00    
       STA    $1700,Y 
       DEY            
       JMP    $2679   
LF787: RTS            

       LDY    $E2     
       SEC            
LF78B: LDA    $1800,Y 
       SBC    $1900,Y 
       STA    $1800,Y 
       DEY            
       BPL    LF78B   
       BCS    LF7A5   
       LDA    $1700,Y 
       SBC    #$00    
       STA    $1700,Y 
       DEY            
       JMP    $2697   
LF7A5: RTS            

       LDY    #$00    
       LDA    $1800,Y 
       CMP    $1900,Y 
       BEQ    LF7B1   
LF7B0: RTS            

LF7B1: CPY    $E2     
       BEQ    LF7B0   
       INY            
       JMP    $26A8   

LF7B9: LDX    #$16        ; finally, back to something important
       STX    INPTCTRL    ; switch out bios and use reset vector
       TXS                ; on cart to start the game.
       SED            
       JMP(LFFFC)     

; Enable 2600 mode
LF7C2: LDA    #$02        ; Enable memory/bios
       STA    INPTCTRL    ; 
       LDX    #$7F
LF7C8: LDA    LF7D4,X     ; again, copy code to ram....
       STA    $0480,X 
       DEX            
       BPL    LF7C8   
       JMP    $0480       ; execute it

; code executed at $0480 (RIOT RAM)

LF7D4: LDA    #$00        ; 
       TAX                ; 
       STA    INPTCTRL    ; Disable 7800 RAM
LF7D9: STA    RSYNC,X     ; Clear the TIA
       INX                ;
       CPX    #$2A        ;
       BNE    LF7D9       ;
       STA    WSYNC       ; wait for sync
       LDA    #$04        ;
       NOP                ;
       BMI    LF80A   
       LDX    #$04    
LF7E9: DEX            
       BPL    LF7E9   
       TXS            
       STA    $0110   
       JSR    $04CB   
       JSR    $04CB   
       STA    RESP1   
       STA    GRP0    
       STA    GRP1    
       STA    PF2     
       NOP            
       STA    WSYNC   
       LDA    #$00    
       NOP            
       BMI    LF80A   
       BIT    RSYNC   
       BMI    LF813   
LF80A: LDA    #$02    
       STA    COLUBK  
       STA    LF112   
       BNE    LF831   
LF813: BIT    WSYNC   
       BMI    LF823   
       LDA    #$02    
       STA    COLUP0  
       STA    LF118   
       STA    LF460   
       BNE    LF831   
LF823: STA    DPPH   
       LDA    #$08    
       STA    GRP0    
       JSR    $04CB   
       NOP            
       BIT    WSYNC   
       BMI    LF80A   
LF831: LDA    #$FD    
       STA    COLUPF  
       JMP(LFFFC)         ; And use the reset vector on the cart to start
       NOP                ; the 2600 game.

LF880: LDA    #$1D        ; this is called any time the self-test fails.
       STA    INPTCTRL    ; Eanble TIA/Cart/lock out INPTCTRL

START:     
       SEI                ; BIOS entry point.  Disable interrupts
       CLD                ; Clear decimal flag
       LDA    #$02        ;
LF888: STA    INPTCTRL    ; Enable 7800 RAM
       LDA    #$FB        ;
       STA    $F5         ;
       LDA    #$12        ;
       STA    $F4         ; set nmi vector to FB12. (shares cleanup of irq)
       LDA    #$7F        ;
       STA    CTRL        ; Turn off DMA
       LDA    #$00        ;
       STA    BACKGRND    ; Background color
       LDX    #$05        ;
LF89C: LDA    LF91D,X     ; looks icky, but it's just a ram test
       LDY    #$00        ;
LF8A1: STA    $2000,Y     ;
       CMP    $2000,Y     ;
       BNE    LF8D0       ; Test failed
       STA    $2100,Y     ;
       CMP    $2100,Y     ;
       BNE    LF8D0       ; Test failed
       DEY                ;
       BNE    LF8A1       ;
       DEX                ;
       BPL    LF89C       ; and right down here, it passes
       LDA    #$43        ; Check RAM 0 mirror
       STA    $2080       ; 
       CMP    $80         ; 
       BNE    LF8CB       ; make sure they match. If not, fail selftest.
       STA    $2180       ; Check RAM 1 mirror
       CMP    $0180       ; 
       BNE    LF8CB       ; make sure they match. If not, fail selftest.
       JMP    LF938       ; continue selftest
LF8CB: LDY    #$04        ;
       JMP    LF880       ; selftest fail.

LF8D0: STA    $1800       ; test store and compare
       CMP    $1800   
       BNE    LF8E2       ; some kind of error code is being determined
LF8D8: LDY    #$01    
       JMP    LF880   

LF8DD: LDY    #$04
       JMP    $F880

LF8E2: LDY    #$03
       JMP    LF880   

LF8E7: LDA    #$00        ; this is a more comprehensive ram test than
       STA    $F0         ; the first routine, and it is called after
       STA    $F2         ; more of the selftest has completed.
       LDY    #$07    
       STY    $F4     
LF8F1: LDA    LF923,Y 
       STA    $F1     
       LDA    LF92B,Y 
       STA    $F3     
       LDX    #$05    
LF8FD: LDA    LF91D,X 
LF900: LDY    #$00    
LF902: STA    ($F0),Y 
       CMP    ($F0),Y 
       BNE    LF8D8   
       STA    ($F2),Y 
       CMP    ($F2),Y 
       BNE    LF8DD   
       DEY            
       BNE    LF902   
       DEX            
       BPL    LF8FD   
       DEC    $F4     
       LDY    $F4     
       BPL    LF8F1   
       JMP    LFB17       ; ram test passed, so jump in here.

; ram test data
LF91D: .byte $00,$FF,$55,$AA,$69,$0F
LF923: .byte $22,$23,$24,$25,$26,$27,$22,$23
LF92B: .byte $18,$19,$1A,$1B,$1C,$1D,$1E,$1F

LF933: LDY    #$00       ; local place for selftest fail branch target
       JMP    LF880   

; 6502 CPU test

LF938: LDA    #$AA       ; test some flags and branches
       BEQ    LF933      ; test failed
       BPL    LF933      ; test failed
       BMI    LF943      ; test passed
       JMP    LF933      ; test failed
LF943: BNE    LF948      ; test passed
       JMP    LF933      ; test failed
LF948: STA    $AA        ; store AA to 00AA
       CMP    $AA        ; compare it back
       BNE    LF933      ; if it doesn't match, selftest fail
       LDA    #$00       ; do some more flag tests
       BNE    LF933      ;
       BMI    LF933      ;
       BPL    LF959      ; test passed
       JMP    LF933      ;
LF959: BEQ    LF95E      ; test passed
       JMP    LF933      ;
LF95E: CMP    #$00       ; test the compare instruction
       BNE    LF933      ;
       BCC    LF933      ;
       BCS    LF969      ; test passed, since they're equal
       JMP    LF933      ;
LF969: CMP    #$01       ; compare it to 01
       BCS    LF933      ;
       BCC    LF972      ; A < 01, so carry is clear
       JMP    LF933      ;
LF972: LDX    #$55       ; test comparisons with the X register
       CPX    #$56       ;
       BEQ    LF933      ;
       STX    $01AA      ;
       CPX    $01AA      ;
       BNE    LF933      ;
       LDY    $AA        ; and with the Y register.
       CPY    #$AB       ;
LF984: BEQ    LF933      ;
       STY    $0155      ; put some stuff in the stack area to test stack
       CPY    $0155      ; and then access this data in many diffeent ways
       BNE    LF933      ;
       DEX               ;
       TXS               ;
       INX               ;
       PLA               ;
       CMP    #$AA       ;
       BNE    LF9EB      ;
       TXA               ;
       PHA               ;
       CPX    $0155      ;
       BNE    LF9EB      ;
       TYA               ;
       CMP    #$AA       ;
       BNE    LF9EB      ;
       TAX               ;
       LDA    $0100,X    ;
       TAY               ;
       CPY    #$55       ;
       BNE    LF9EB      ;
       LDA    VSYNC,X    ;
       CMP    $AA        ;
       BNE    LF9EB      ;
       CMP    #$AA       ;
       BNE    LF9EB      ;
       EOR    #$FF       ;
       STA    $0000,Y    ;
       CMP    $55        ;
       BNE    LF9EB      ;
       CMP    $0100,Y    ;
       BNE    LF9EB      ;
       CMP    $20AB,X    ;
       BNE    LF9EB      ;
       LDA    #$20       ;
       STA    $F1        ;
       LDA    #$CC       ;
       STA    $F0        ;
       STA    ($46,X)    ;
       CMP    $CC        ;
       BNE    LF9EB      ;
       STA    ($F0),Y    ;
       CMP    $2121      ;
       BNE    LF9EB      ;
       LDA    #$EE       ; test the indirect jump by setting up a jump
       STA    $F0        ; to F9EE
       LDA    #$F9       ;
       STA    $F1        ;
       JMP($00F0)        ; and do it.

LF9E8: JMP    $F9EB

LF9EB: JMP    LF933


LF9EE: LDA    #$55       ; now test out the math functions.
       CLC            
       ADC    #$55    
       NOP            
       BCS    LF9EB      ; test addition.
       BPL    LF9EB   
       BEQ    LF9EB   
       CMP    #$AA       ; make sure it worked
       BNE    LF9EB   
       ADC    #$55       ; test addition again.
LFA00: NOP            
       BCC    LF9EB   
       BMI    LF9EB   
       BNE    LF9EB   
       SBC    #$55       ; test subtraction
       BCS    LF9EB   
       BPL    LF9EB   
       BEQ    LF9EB   
       CMP    #$AB       ; make sure it worked
       BNE    LF9EB   
       CLC            
       SBC    #$AA       ; test subtraction again
       BCC    LF9EB   
       BMI    LF9EB   
       BNE    LF9EB   
       LDA    #$FF       ; set up a stack
       TAX               ; and do all kinds of stuff in it for tests
       INX            
       BNE    LFA58   
       DEX            
       BEQ    LFA58   
       BPL    LFA58   
       CPX    #$FF    
       BNE    LFA58   
       TAY            
       INY            
       BNE    LFA58   
       DEY            
       BEQ    LFA58      
       INY            
       BNE    LFA58   
       STA    $F0     
       INC    $F0     
       BNE    LFA58   
       CPY    $F0     
       BNE    LFA58   
       DEC    $F0     
       BEQ    LFA58   
       CMP    $F0     
       BNE    LFA58   
       LDA    #$AA    
       CLC            
       ROL    A          ; now we get onto the more complex math instrs
       ROL    A       
       ROL    A       
       CMP    #$52    
       BNE    LFA58      ; make sure rotate left works.
       ROR    A       
       ROR    A       
       ROR    A       
       CMP    #$AA    
       BEQ    LFA5B      ; test rotate right
LFA58: JMP    LF933      ; fail!

LFA5B: ASL    A          ; test arithmetic shift left
       BCC    LFA58   
       ASL    A       
       BCS    LFA58   
       ASL    A       
       CMP    #$50    
       BNE    LFA58   
       EOR    #$05    
       LSR    A          ; and logical shift right
       BCC    LFA58   
       LSR    A       
       BCS    LFA58   
       LSR    A       
       CMP    #$0A    
       BNE    LFA58   
       LDA    #$55       ; now test the ands and ors.
       ORA    #$1B    
       CMP    #$5F    
       BNE    LFA58   
       AND    #$55    
       AND    #$1B    
       CMP    #$11    
       BNE    LFA58   
       ORA    #$55    
       EOR    #$1B       ; and the eors
       CMP    #$4E    
       BNE    LFA58   
       JSR    LFA91      ; test jump subroutine instruction
       JMP    LFA58      ; if we return, fail

LFA91: TSX               
       CPX    #$52       ; check stack pointer
       BNE    LFA58      ; fail if not right
       PLA            
       CMP    #$8D    
       BNE    LFA58   
       PLA            
       CMP    #$FA    
       BNE    LFA58      ; get the old return address off the stack
       LDA    #$F8    
       PHA            
       LDA    #$E6    
       PHA               ; and make our own
       RTS               ; and 'return' to F8E7

       JMP    LFA58      ; another jump to catch a failure

; Interrupt routine  NMI. 

LFAAA: TXA          ;Save A
       PHA          ;  
       LDA    #$43  ;Setup control register  
       STA    CTRL  ; 
       LDX    #$0F  ; Handle the color scrolling in the FUJI    
       LDA    $EF     
       STA    WSYNC ;Wait for Sync   
       BIT    $F3     
       BVC    LFAC0   
       BPL    LFABE   
LFABC: STA    WSYNC ;Wait for 3 scanlines 
LFABE: STA    WSYNC ;    
LFAC0: STA    WSYNC ;   
       SEC            
       SBC    #$10  
       CMP    #$10    
       BCS    LFACB   
       SBC    #$0F    
LFACB: STA    WSYNC    
       DEX            
       BPL    LFABC   ;Branch to do next section of fuji
       LDX    #$40    ;set 160x2/160x4 mode
       STX    CTRL    ;  
       AND    #$F0    ;
       ORA    #$0E    ;set Palette 1 color 3
       STA    P1C3    ;
       LDA    $EF     ;
       AND    #$F0    ;
       ORA    #$06    ;set Palette 1 color 1
       STA    P1C1    ;
       AND    #$F0    
       CLC            
       ADC    #$40    
       BCC    LFAEB   
       ADC    #$0F    
LFAEB: ORA    #$03   ;set Palette 1 color 2  
       STA    P1C2  
       DEC    $F1     
       BPL    LFB0C   
       LDA    $F3     
       ADC    #$60    
       BCC    LFB0A   
       LDA    $EF     
       CLC            
       ADC    #$10    
       BCC    LFB02   
       ADC    #$0F    
LFB02: STA    $EF     
       LDA    $F2     
       STA    $F1     
       LDA    #$00    
LFB0A: STA    $F3     
LFB0C: LDA    #$02    
       STA    $F0     
       PLA            
       TAX            
       PLA            
       RTI            

LFB14: JMP    LFB14   

LFB17: LDX    #$FF       ; selftest has passed, start system init
       TXS               ; set up a stack
       LDA    #$00       ; Clear TIA/Maria registers
       TAX               ;
LFB1D: STA    $01,X ;    ;
       INX               ;
       CPX    #$2C       ;
       BNE    LFB1D      ; 
       LDA    #$02       ;
       STA    INPTCTRL   ; Enable 7800 RAM 
       LDX    #$00       ;
       STX    BACKGRND   ; Set background color 
LFB2C: LDA    LF400,X    ; copy the authentication and title screen to 
       STA    $2300,X    ; ram
       LDA    LF500,X    ;
       STA    $2400,X    ;
       LDA    LF600,X    ;
       STA    $2500,X    ;
       LDA    LF700,X    ;
       STA    $2600,X    ;
       LDA    LF800,X    ;
       STA    $2700,X    ;
       LDA    LFBBE,X    ;
       STA    $2200,X    ;
       CPX    #$00       ;
       BMI    LFB7E      ;
       LDA    LFC4B,X     ;
       STA    $1F84,X     ;
       LDA    LFCC6,X     ;
       STA    $1984,X     ;
       LDA    LFD3D,X     ;
       STA    $1A84,X     ;
       LDA    LFDB4,X     ;
       STA    $1B84,X     ;
       LDA    LFE18,X     ;
       STA    $1C84,X     ;
       LDA    LFE57,X     ;
       STA    $1D84,X     ;
       LDA    LFE96,X     ;
       STA    $1E84,X     ;
LFB7E: DEX                ;
       BNE    LFB2C       ;
       JMP    $2306       ; and execute it

;Start display of Atari logo

LFB84: LDA    LFFF9      ; Read ROM start byte from cart
       AND    #$04       ; Is rom start greater then $4000?
       BEQ    LFBBD      ; Branch if not
       LDA    #$03      
       STA    $F1     
       STA    $F2     
       LDA    #$49    
       STA    $EF     
       LDA    #$66       ;Palette 1 Color 1
       STA    P1C1       ;
       LDA    #$56       ;Palette 1 Color 2
       STA    P1C2       ;
       LDA    #$2E       ;Palette 1 Color 3
       STA    P1C3       ;
       LDA    #$AA       ;Set NMI vector to FAAA
       STA    $F4        ;
       LDA    #$FA       ;
       STA    $F5        ;
LFBA9: BIT    MSTAT      ;Check VBLANK status
       BMI    LFBA9      ;Wait till end of VBLANK
LFBAD: BIT    MSTAT      ;Check BLANK status
       BPL    LFBAD      ;Wait for start of next VBLANK
       LDA    #$84       ;Set Display list pointer to $1f84
       STA    DPPL       ;
       LDA    #$1F       ;
       STA    DPPH       ;
       LDA    #$43       ;Maria mode = DMA on/320A or 320C
       STA    CTRL       ;
LFBBD: RTS               ;

; Graphics and Display List Data

LFBBE:                                  ;$2200   Display Lists

       .byte $84,$1F,$19,$BB,           ;$2200   Blank space
             $00,$00

       .byte $84,$40,$19,$1F,$BB,       ;$2206   First DL on screen
             $00,$00

       .byte $85,$1C,$19,$4A,           ;$220D   Blank space before Fuji
             $00,$00

       .byte $89,$1C,$19,$4A,           ;$2213   Fuji line 1
             $00,$00

       .byte $8D,$1C,$19,$48,           ;$2219   Fuji line 2
             $00,$00

       .byte $91,$1B,$19,$46,           ;$221F   Fuji line 3
             $00,$00

       .byte $96,$19,$19,$42,           ;$2225   Fuji line 4
             $00,$00

       .byte $9D,$17,$19,$3E,           ;$222B   Fuji line 5
             $00,$00

       .byte $A6,$17,$19,$3E,           ;$2231   Fuji line 6
             $00,$00

       .byte $AF,$2C,$1C,$00,           ;$2237   Start of Atari
             $AF,$2C,$1C,$50,                    and between lines
             $00,$00

       .byte $AF,$2C,$1D,$00,           ;$2241   End of Atari
             $AF,$2C,$1D,$50,
             $00,$00

       .byte $AF,$2D,$19,$28,           ;$224B    Atari line 1
             $00,$00

       .byte $C2,$2D,$19,$28,           ;$2251    Atari line 2
             $00,$00

       .byte $D5,$2D,$19,$28,           ;$2257     Atari line 3
             $00,$00
                                                   
       .byte $E8,$2D,$19,$28,           ;$225D     Atari line 4
             $00,$00

       .byte $AF,$2D,$1A,$28,           ;$2263     Atari line 5
             $00,$00

       .byte $C2,$2D,$1A,$28,           ;$2269     Atari line 6
             $00,$00

       .byte $D5,$2D,$1A,$28,           ;$226F     Atari line 7
             $00,$00

       .byte $E8,$2D,$1A,$28,           ;$2275     Atari line 8
             $00,$00

       .byte $AF,$2D,$1B,$28,           ;$227B     Atari line 9
             $00,$00

       .byte $C2,$2D,$1B,$28,           ;$2281     Atari line 10
             $00,$00

       .byte $D5,$2D,$1B,$28,           ;$2287     Atari line 11
             $00,$00

; $1F84  Display List List

LFC4B: .byte $0F,$22,$06,      ;Blank space
             $0F,$22,$00,      ;
             $0F,$22,$00,      ;
             $0F,$22,$00,      ;
             $03,$22,$00,      ;
             $85,$22,$0D,      ;DLI
             $05,$22,$13,      ;Draw Fuji
             $05,$22,$19,      ;
             $05,$22,$1F,      ;
             $05,$22,$25,      ;
             $05,$22,$2B,      ;
             $05,$22,$31,      ;
             $0F,$22,$00,      ;Blank area
             $01,$22,$37,      ;Draw "ATARI"
             $00,$22,$4B,      ;Line 1 
             $02,$22,$37,
             $00,$22,$51,      ;Line 2
             $02,$22,$37,
             $00,$22,$57,      ;Line 3
             $02,$22,$37,
             $00,$22,$5D,      ;Line 4
             $02,$22,$37,
             $00,$22,$63,      ;Line 5
             $02,$22,$37,
             $00,$22,$69,      ;Line 6
             $02,$22,$37,
             $00,$22,$6F,      ;Line 7
             $02,$22,$37,
             $00,$22,$75,      ;Line 8
             $02,$22,$37,
             $00,$22,$7B,      ;Line 9
             $02,$22,$37,
             $00,$22,$81,      ;Line 10
             $02,$22,$37,
             $00,$22,$87,      ;Line 11
             $01,$22,$41,
             $0F,$22,$00,      ;Blank Space
             $0F,$22,$00,      ;
             $0F,$22,$00,      ;
             $0F,$22,$00,      ;
             $0F,$22,$00       ;


;Atari data

$19AF  .byte $00,$00,$0C,$00,$3F,$FF,$FF,$FF,$F0,$00,$C0,$00,$00,$3F,$FF,$FF,$00,$03,$FC,
$19C2  .byte $00,$00,$3F,$00,$3F,$FF,$FF,$FF,$F0,$03,$F0,$00,$00,$3F,$FF,$FF,$FC,$03,$FC,
$19D5  .byte $00,$00,$FF,$C0,$00,$03,$FF,$00,$00,$0F,$FC,$00,$00,$3F,$F0,$03,$FF,$C3,$FC,
$19E8  .byte $00,$03,$FF,$F0,$00,$03,$FF,$00,$00,$3F,$FF,$00,$00,$3F,$F0,$00,$3F,$C3,$FC

$1AAF  .byte $00,$0F,$F3,$FC,$00,$03,$FF,$00,$00,$FF,$3F,$C0,$00,$3F,$F0,$00,$FF,$C3,$FC,
$1AC2  .byte $00,$3F,$C0,$FF,$00,$03,$FF,$00,$00,$FC,$0F,$F0,$00,$3F,$F0,$3F,$FC,$03,$FC,
$1AD5  .byte $00,$FF,$00,$3F,$C0,$03,$FF,$00,$0F,$F0,$03,$FC,$00,$3F,$F0,$FF,$C0,$03,$FC,
$1AE8  .byte $03,$FF,$FF,$FF,$F0,$03,$FF,$00,$3F,$FF,$FF,$FF,$00,$3F,$F0,$3F,$F0,$03,$FC

$1BAF  .byte $0F,$FF,$FF,$FF,$FC,$03,$FF,$00,$FF,$FF,$FF,$FF,$C0,$3F,$F0,$0F,$FC,$03,$FC,
$1BC2  .byte $3F,$F0,$0F,$03,$FF,$03,$FF,$03,$FF,$00,$00,$3F,$F0,$3F,$F0,$03,$FF,$03,$FC,
$1BD5  .byte $FF,$C0,$00,$00,$FF,$C3,$FF,$0F,$FC,$00,$00,$0F,$FC,$3F,$F0,$00,$FF,$C3,$FC

; $1984
LFCC6: .byte $00,$7C,$7F,$8F,$80,$FC,$7F,$8F,$C0,$1F,$87,$F8,$7E,$0F,$E0,$7F
       .byte $81,$FC,$07,$FF,$80,$7F,$80,$7F,$F8,$1F,$FF,$F0,$00,$7F,$80,$03
       .byte $FF,$FE,$1F,$00,$00,$00,$7F,$80,$00,$00,$3E,


; $1A84
LFD3D: .byte $00,$7C,$7F,$8F,$80,$7C,$7F,$8F,$80,$1F,$87,$F8,$7E,$0F,$F0,$7F
       .byte $83,$FC,$01,$FF,$80,$7F,$80,$7F,$E0,$1F,$FF,$F8,$00,$7F,$80,$07
       .byte $FF,$FE,$1F,$F0,$00,$00,$7F,$80,$00,$03,$FE,


; $1B84
LFDB4: .byte $00,$7C,$7F,$8F,$80,$7C,$7F,$8F,$80,$1F,$87,$F8,$7E,$07,$F0,$7F
       .byte $83,$F8,$00,$FF,$C0,$7F,$80,$FF,$C0,$1F,$FF,$FC,$00,$7F,$80,$0F
       .byte $FF
LFDD5: .byte $FE,$1F,$FC,$00,$00,$7F,$80,$00,$0F,$FE,


; $1C84
LFE18: .byte $00,$7C,$7F,$8F,$80,$7C,$7F,$8F,$80,$0F,$87,$F8,$7C,$07,$F0,$7F
       .byte $83,$F8,$00,$7F,$C0,$7F,$80,$FF,$80,$1F,$FF,$FE,$00,$7F,$80,$1F
       .byte $FF,$FE,$1F,$FF,$00,$00,$7F,$80,$00,$3F,$FE,$55,$55,$55,$55,$55
       .byte $55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55

; $1D84
LFE57: .byte $00,$7C,$7F,$8F,$80,$7C,$7F,$8F,$80,$0F,$C7,$F8,$FC,$03,$F0,$7F
       .byte $83,$F0,$00,$3F,$E0,$7F,$81,$FF,$00,$01,$FF,$FE,$00,$7F,$80,$1F
       .byte $FF,$E0,$1F,$FF,$C0,$00,$7F,$80,$00,$FF,$FE,$AA,$AA
LFE84: .byte $AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
       .byte $AA,$AA

;$1E84
LFE96: .byte $00,$7C,$7F,$8F,$80,$7C,$7F,$8F,$80,$0F,$C7,$F8,$FC,$03,$F8,$7F
       .byte $87,$F0,$00,$1F,$E0,$7F,$81,$FE,$00,$00,$1F,$FF,$00,$7F,$80,$3F
       .byte $FE,$00,$1F,$FF,$E0,$00,$7F,$80,$01,$FF,$FE,$55,$55,$55,$55,$55
       .byte $55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$55
LFED5: .byte $09,$CA,$C9,$C6,$B4,$12,$08,$1B,$60,$58,$81,$4B,$86,$01,$D8,$BF
       .byte $D9,$25,$A0,$7B,$DC,$32,$79,$84,$3B,$7C,$BC,$2F,$E2,$E2,$FA,$8D
       .byte $0A,$00,$3B,$C5,$EC,$AF,$2D,$8A,$CD,$06,$93
LFF00: .byte $6A,$A5,$14,$46,$77,$C4,$6A,$B2,$53,$36,$EF,$8C,$CE,$0C,$A2,$68
       .byte $71,$D3,$73,$E8,$F7,$6D,$06,$B5,$20,$EF,$23,$47,$0C,$51,$55,$C8
       .byte $FE,$F4,$58,$C4,$3F,$20,$A7,$67,$38,$B0,$76,$E2,$C4,$D8,$05,$63
       .byte $F8,$3C,$58,$3B,$2D,$22,$CC,$88,$B3,$71,$8F,$1D,$80,$0A,$87,$BD
       .byte $A1,$59,$23,$E9,$70,$E2,$D3,$EC,$46,$68,$80,$42,$39,$EA,$FF,$FF

LFFEE: .byte $47,$43,$43,$28,$43,$29 ; 'GCC(C)'
       .byte $31,$39,$38,$34,$2D,$F7 ; '1984-'

LFFFA: .byte $00,$F0 ; system vector - nmi
LFFFC: .byte $84,$F8 ; system vector - reset
LFFFE: .byte $AA,$FA ; system vector - irq
