--- pitfall.asm	Tue Jun 11 20:56:52 2013
+++ pitfallT.asm	Thu Jun 13 01:28:50 2013
@@ -5,6 +5,11 @@
 ; Analyzed, labeled and commented
 ;  by Thomas Jentzsch (JTZ)
 ; Last Update: 09.10.2001 (v0.9)
+; Sam Trenholme: Trainer: Smaller map, unlimited (OK, 60) lives, no walls
+; Game select starts hard practice mode with alternate tiny map where any point-losing 
+; error (hitting a log, falling in to hole) is fatal and there is only one
+; minute of play.  The run ends if the player gets to the right; it is not
+; possible to shortcut this by running left from the start screen
 
 ; Scene generation:
 ; The 255 scenes are randomly generated through a "bidirecional" LFSR. This
@@ -38,6 +43,7 @@
 ;   that (s. FRAMERATE etc.).
 
 
+TIA_BASE_READ_ADDRESS = $30
     processor 6502
     include vcs.h
 
@@ -53,10 +59,10 @@
 NTSC            = 1                     ; compile for NTSC
   IF NTSC
 FRAMERATE       = 60
-STARTTIME       = $20
+STARTTIME       = $60
   ELSE
 FRAMERATE       = 60                    ; 50    use these values to..
-STARTTIME       = $20                   ; $24   ..adjust the PAL timer
+STARTTIME       = $60                   ; $24   ..adjust the PAL timer
   ENDIF
 
 
@@ -65,7 +71,7 @@
 ;===============================================================================
 
 ; initial value for the random number generator:
-RAND_SEED       = $c4                   ; defines the start scene of the game
+RAND_SEED       = $c4                 ; defines the start scene of the game
 
 ; color constants:
   IF NTSC
@@ -190,7 +196,7 @@
     SEG.U   Variables
     ORG     $80
 
-livesPat            .byte   ;           number of lives, stored as displayed pattern ($a0 = 3, $80 = 2, $00 = 1)
+;livesPat            .byte   ;           number of lives, stored as displayed pattern ($a0 = 3, $80 = 2, $00 = 1)
 random              .byte   ;           all scenes are generated randomly with this
 random2             .byte   ;           used for random object animation
 joystick            .byte   ;           stores joystick directions
@@ -235,6 +241,7 @@
 scoreHi             .byte   ;           3 BCD score bytes
 scoreMed            .byte
 scoreLo             .byte
+startTime	    .byte ; 
 timerHi             .byte   ;           2 BCD timer bytes
 timerMed            .byte
 timerLo             .byte   ;           decease timer every 60th frame
@@ -291,6 +298,7 @@
     sei                     ; 2
     cld                     ; 2
     ldx    #$00             ; 2
+    ldy    #RAND_SEED
 Reset:
     lda    #$00             ; 2
 .loopClear:
@@ -298,6 +306,7 @@
     txs                     ; 2
     inx                     ; 2
     bne    .loopClear       ; 2³
+    sty    random           ; 3
 
     jsr    InitGame         ; 6
 
@@ -324,7 +333,7 @@
 ; pointer sets are used, because the wall is much taller than
 ; the scorpion.
 ; JTZ: two color pointers aren't necessary!
-    ldy    #<ScorpionColor  ; 2
+;    ldy    #<Scorpion0  ; 2
     ldx    #<Scorpion0      ; 2
     lda    xPosScorpion     ; 3
     lsr                     ; 2                 animate scorpion
@@ -339,10 +348,10 @@
     ldy    #<WallColor      ; 2                  yes,..
     ldx    #<Wall           ; 2
     stx    wallPatPtr       ; 3                 ..load pointers at ladder data
-    sty    wallColPtr       ; 3
+;    sty    wallColPtr       ; 3
 .noLadder:
     stx    undrPatPtr       ; 3                 set scorpion or ladder pointers
-    sty    undrColPtr       ; 3
+;    sty    undrColPtr       ; 3
 
 ; calculate pits, quicksand etc.:
     ldx    sceneType        ; 3
@@ -464,7 +473,7 @@
     inx                     ; 2                 seconds
     ldy    #8               ; 2
     jsr    BCD2DigitPtrs    ; 6
-    lda    livesPat         ; 3                 show lives before time
+    lda    #0	            ; 3                 show lives before time
     sta    temp3            ; 3
     lda    #<Space          ; 2
     sta    digitPtr         ; 3
@@ -1224,7 +1233,9 @@
     sta    COLUP0           ; 3
     lda    (undrPatPtr),y   ; 5
     sta    GRP1             ; 3
-    lda    (undrColPtr),y   ; 5
+;    lda    (undrColPtr),y   ; 5
+    lda    #WHITE
+    bit $00; Cycles *must* match here in kernel
   IF SCREENSAVER
     and    SS_Mask          ; 3
   ELSE
@@ -1323,16 +1334,16 @@
     lda    soundIdx         ; 3
     cmp    #SOUND_FALLING-1 ; 2                 dead tune at end of playing?
     bne    .slipDecrease    ; 2³                 no, skip decrease
-; Harry is loosing a live:
-    lda    livesPat         ; 3                 any more lives?
-    beq    .slipDecrease    ; 2³                 no, skip decrease
-  IF TRAINER
-    FILL_NOP 4
-  ELSE
-    asl                     ; 2                  yes, decrease lives
-    asl                     ; 2
-    sta    livesPat         ; 3
-  ENDIF
+; Harry is losing a life:
+; TRAINER: Decrease time by one minute if life lost
+    lda timerHi
+    beq .slipDecrease ; He's dead Jim (no minutes left means dead)
+    sed 
+    sec 
+    sbc #1
+    cld 
+    sta    timerHi        ; 3
+.noDownTimer:
     lda    #NOREFLECT       ; 2
     sta    reflectHarry     ; 3
     sta    noGameScroll     ; 3
@@ -1507,7 +1518,7 @@
     FILL_NOP 2
   ENDIF
     lda    timerHi          ; 3
-    cmp    #STARTTIME       ; 2                 timer at 20:00?
+    cmp    startTime        ; 2                 timer at 60:00/0:00?
     bne    .noMove          ; 2³                 no, skip
     stx    noGameScroll     ; 3                  yes, game is running
 .noMove:
@@ -1515,15 +1526,26 @@
 ; read RESET switch:
     lda    SWCHB            ; 4
     lsr                     ; 2                 RESET pressed?
-    bcs    .noReset         ; 2³                 no, skip
+    bcs    .noReset         ; 2                 no, skip
   IF SCREENSAVER
     ldx    #SS_Delay        ; 2                  yes, load init-values offset..
   ELSE
     ldx    #frameCnt        ; 2                  yes, load init-values offset..
   ENDIF
+    ldy    #RAND_SEED
     jmp    Reset            ; 3                 ..and jump to Reset
 
 .noReset:
+    lsr			    ; SELECT pressed
+    bcs    .noSelect	    ;
+  IF SCREENSAVER
+    ldx    #SS_Delay        ; 2                  yes, load init-values offset..
+  ELSE
+    ldx    #frameCnt        ; 2                  yes, load init-values offset..
+  ENDIF
+    ldy    #$87 ; Cobra 8-location mini-jungle
+    jmp    Reset 
+.noSelect:
     lda    noGameScroll     ; 3                 game running?
     beq    .processHarry    ; 2³                 yes, process Harry
     jmp    ProcessObjects   ; 3                  no, skip Harry, goto objects
@@ -1561,6 +1583,9 @@
     bne    .skipFalling     ; 2³+1
     lda    #SOUND_FALLING   ; 2                 Harry is falling into a hole
     sta    soundIdx         ; 3                 start falling-sound
+    lda    startTime
+    and  #3
+    bne .practiceKill
     lda    #$00             ; 2
     jsr    DecScoreHi       ; 6                 subtract 100 points from score
 .skipFalling:
@@ -1570,6 +1595,7 @@
     bne    .endDoJump       ; 2³                 no, skip
     tya                     ; 2                 ladder in scene?
     bne    .endDoJump       ; 2³                 no, skip kill
+.practiceKill:
     jmp    KilledHarry      ; 3                  yes, Harry is killed
 
 .stopJump:
@@ -1651,6 +1677,9 @@
     bne    .endCollision    ; 3
 
 .noTreasure1:
+    lda    startTime
+    cmp    #STARTTIME
+    bne    .noWallHit ; Kill Harry if he touches log in training course
     lda    objectType       ; 3
     cmp    #ID_FIRE         ; 2                 fire or cobra?
     bcc    .hitLogs         ; 2³                 no, hit by rolling logs
@@ -1680,28 +1709,7 @@
     jmp    .swingLiana      ; 3
 
 .checkWallHit:
-    lda    wallPatPtr       ; 3
-    cmp    #<Wall           ; 2                 wall displayed in scene?
-    bne    .noWallHit       ; 2³                 no, skip
-    lda    #$01             ; 2                  yes, make some noise
-    sta    AUDC1            ; 3
-    lda    xPosHarry        ; 3                 determine where Harry hit the wall
-    cmp    #140             ; 2                 right wall from the right?
-    bcs    .hitFromRight    ; 2³                 yes, continue
-    cmp    #13              ; 2                 left wall from the left?
-    bcc    .hitFromLeft     ; 2³                 yes, continue
-    cmp    #80              ; 2                 left or right wall?
-    bcs    .hitFromLeft     ; 2³
-.hitFromRight:
-    inc    xPosHarry        ; 5                 bounce back one pixel and..
-    ldx    #MOVE_RIGHT      ; 2                 ..change direction to right
-    bne    .contWallHit     ; 3
-
-.hitFromLeft:
-    dec    xPosHarry        ; 5                 bounce back one pixel and..
-    ldx    #MOVE_LEFT       ; 2                 ..change direction to left
-.contWallHit:
-    stx    oldJoystick      ; 3
+    jmp    KilledHarry      ; 3                 Only scorpions; Harry killed
 
 ; let the liana swing:
 .swingLiana:
@@ -1938,15 +1946,18 @@
 .endAnimHarry:
 
 ; goto next scene, if Harry has reached border of current scene:
-    ldx    #0               ; 2                 move one scene
+    ldx    #2               ; 2                 move one scene (3 rounds)
     lda    yPosHarry        ; 3
     cmp    #64              ; 2                 Harry at underground?
-    bcc    .oneScene        ; 2³                 yes, move one scene
-    ldx    #2               ; 2                  no, move three scenes
+    bcc    .oneScene        ; 2³                 yes, move one scene (3r)
+    ldx    #8               ; 2                  no, move three scenes (9r)
 .oneScene:
     lda    xPosHarry        ; 3
     cmp    #XMIN_HARRY      ; 2
     bcs    .notAtLeft       ; 2³
+    lda    random
+    cmp    #$87
+    beq    .stopLeft
     jsr    LeftRandom       ; 6
     lda    #XMAX_HARRY      ; 2
     sta    xPosHarry        ; 3
@@ -1954,6 +1965,7 @@
     cmp    #XMAX_HARRY+1    ; 2
     bcc    .notAtRight      ; 2³
     jsr    RightRandom      ; 6
+.stopLeft:
     lda    #XMIN_HARRY      ; 2
     sta    xPosHarry        ; 3
 .notAtRight:
@@ -2167,10 +2179,16 @@
     asl                     ; 2
     sta    yPosHarry        ; 3
     sta    scoreMed         ; 3                 = $20
-  IF STARTTIME != $20
+    cpy    #RAND_SEED
+    beq    .60minutes
+    inc    startTime;
+    inc    timerHi; 
+    bne    .1minuteDone
+.60minutes:
     lda    #STARTTIME
-  ENDIF
     sta    timerHi          ; 3
+    sta    startTime        ; 3
+.1minuteDone
 
     ldx    #27              ; 2
 .loopInit:
@@ -2183,27 +2201,22 @@
     sta    timerLo          ; 3
     lda    #31              ; 2
     sta    treasureCnt      ; 3
-    lda    #%10100000       ; 2                 3 lives
-    sta    livesPat         ; 3
-    lda    #RAND_SEED       ; 2                 set starting scene
-    sta    random           ; 3
+;    lda    #%10100000       ; 2                 3 lives
+;    sta    livesPat         ; 3
     bne    ContRandom       ; 3
 
 LeftRandom SUBROUTINE
 ; generate new random scene on the left:
 .loopRandom:
-; random' = random >> 1 | (bit4^bit5^bit6^bit1) * $80
-    lda    random           ; 3
-    asl                     ; 2
-    eor    random           ; 3
-    asl                     ; 2
-    eor    random           ; 3
-    asl                     ; 2
-    asl                     ; 2
-    rol                     ; 2
-    eor    random           ; 3
+; add-xor-rotate: r = (r >> 1) | (r << 7); r -= 16; r ^= 10 (0xa);
+;    lda    random           ; ?
     lsr                     ; 2
-    ror    random           ; 5
+    ror    random           ; 3
+    lda    random           ; 3
+    sec                     ; 2
+    sbc    #$10             ; 3
+    eor    #$0a             ; 3
+    sta    random           ; ?
     dex                     ; 2
     bpl    .loopRandom      ; 2³
 ContRandom:
@@ -2230,11 +2243,12 @@
     cmp    #HOLE3_SCENE+1   ; 2                 scene with hole(s)?
     bcs    .setFlag         ; 2³                 no, skip
     ldy    #WITHLADDER      ; 2                  yes, enable ladder
-    ldx    #17              ; 2                 left wall x-position
+; TRAINER no walls
+    ldx    #0              ; 2                 left wall x-position
     lda    random           ; 3
-    asl                     ; 2                 position of the wall? (bit 7)
-    bcc    .setFlag         ; 2³                 left, skip
-    ldx    #136             ; 2                  right wall x-position
+    lsr                     ; 2                 position of the wall? (bit 7)
+    bcs    .setFlag         ; 2³                 left, skip
+    ldx    #0             ; 2                  right wall x-position
 .setFlag:
     sty    ladderFlag       ; 3
     stx    xPosScorpion     ; 3                 also used for wall position
@@ -2639,6 +2653,7 @@
 KilledHarry SUBROUTINE
     lda    #SOUND_DEAD      ; 2
     sta    soundIdx         ; 3
+EndGame SUBROUTINE
     lda    #$84             ; 2                 start copyright..
     sta    noGameScroll     ; 3                 ..animation
     jmp    ProcessObjects   ; 3
@@ -2842,21 +2857,6 @@
     .byte %00000000; |        |
 Wall:
     .byte %11111110; |XXXXXXX |
-    .byte %10111010; |X XXX X |
-    .byte %10111010; |X XXX X |
-    .byte %10111010; |X XXX X |
-    .byte %11111110; |XXXXXXX |
-    .byte %11101110; |XXX XXX |
-    .byte %11101110; |XXX XXX |
-    .byte %11101110; |XXX XXX |
-    .byte %11111110; |XXXXXXX |
-    .byte %10111010; |X XXX X |
-    .byte %10111010; |X XXX X |
-    .byte %10111010; |X XXX X |
-    .byte %11111110; |XXXXXXX |
-    .byte %11101110; |XXX XXX |
-    .byte %11101110; |XXX XXX |
-    .byte %11101110; |XXX XXX |
 Bar0:
     .byte %00000000; |        |
     .byte %11111000; |XXXXX   |
@@ -2953,9 +2953,9 @@
     .byte GREY-2, GREY-2, GREY-2, GREY-2, GREY-2, GREY-2, GREY-2
     .byte GREY-2, GREY-2, GREY-2, GREY-2, BROWN, GREY-2, GREY-2
     FILL_NOP 2         ; JTZ: the moneybag is only 9 lines tall
-ScorpionColor:
-    .byte WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE
-    .byte WHITE, WHITE, WHITE
+;ScorpionColor:
+;    .byte WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE
+;    .byte WHITE, WHITE, WHITE
      FILL_NOP 5         ; JTZ: the scorpion is only 11 lines tall
   ELSE
 LogColor:
@@ -2973,9 +2973,9 @@
 MoneyBagColor:
     .byte GREY-2, GREY-2, GREY-2, GREY-2, GREY-2, GREY-2, GREY-2, GREY-2
     .byte GREY-2, GREY-2, GREY-2, GREY-2, BROWN, GREY-2, GREY-2, GREY-2
-ScorpionColor:
-    .byte WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE
-    .byte WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE
+;ScorpionColor:
+;    .byte WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE
+;    .byte WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE
   ENDIF
 WallColor:
     .byte GREY, DARK_RED, DARK_RED, DARK_RED, GREY, DARK_RED, DARK_RED, DARK_RED
@@ -3010,20 +3010,29 @@
 RightRandom SUBROUTINE
 ; generate new random scene on the right:
 .loopRandom:
-; random' = random << 1 | (bit3^bit4^bit5^bit7)
-    lda    random           ; 3
-    asl                     ; 2
-    eor    random           ; 3
-    asl                     ; 2
-    eor    random           ; 3
-    asl                     ; 2
-    asl                     ; 2
-    eor    random           ; 3
+; ARX-style code: a=16; b=10 (0xa); r ^= b; r += a; r = (r << 1) | (r >> 7);
+    lda    random           ; ?
+    eor    #$0a             ; ?
+    clc                     ; ?
+    adc    #$10             ; ?
+    sta    random           ; 3
     asl                     ; 2
     rol    random           ; 5
     dex                     ; 2
     bpl    .loopRandom      ; 2³
+    lda    random
+    cmp    #$87
+    beq    .endGame
+    cmp    #$96
+    bne    .cRandom
+    sta    startTime
+.cRandom:
     jmp    ContRandom       ; 3
+.endGame:
+    lda    startTime
+    bpl    .cRandom
+    jmp    EndGame
+;    jmp    KilledHarry
 
 ; low pointer to harry data:
 HarryPtrTab:
