;---------------------------------------------- ;лллллллллллллллллллллллллллллллллллллллллллллл ;лллллллллллллллл LA TOUR DE HANOI лллллллллллл ;лллллллллллллллллллллллллллллллллллллллллллллл ; ; made by Alban Gervaise ; 28/06/98 ; v0.1 ; ; *: signifie voir au bas car explication est necessaire ; #include "asm86.h" #include "ti86asm.inc" #include "ti86math.inc" #include "ti86ops.inc" #include "ti86abs.inc" .org _asm_exec_ram ; on commence le programme en assembleur call _runindicoff ; pas d'indicateur de marche call _clrLCD ; efface l'ecran ld hl, $0002 ; positionne le curseur ld (_curRow), hl ; au debut de la deuxieme ligne ld hl, menustr ; met l'addresse du string a affiche dans HL call _puts ; affiche call pause ; une petite pause (call $554A) call _clrLCD ; efface l'ecran ld hl, $0002 ; met 2 dans HL (seconde ligne) ld (_curRow), hl ld hl, combien call _puts ld a, 5 ; met 5 dans A ld (nombre_piece), a ; on veut 5 pieces call print_nombre_piece ; on affiche ce nombre ld a, 43 ; met 43 dans A (chiffre au hasard!) ld (inutil), a ; on le met dans inutile *1 choose_loop: ; choose_loop pour choisir le nombre de pieces call GET_KEY ; quelle touche est mise? cp K_ENTER ; est-ce ENTER ? jp z, start_game ; si oui aller a start_game cp K_LEFT ; est-ce gauche ? jr z, moins ; si oui aller a moins car ca decremente les pieces cp K_RIGHT ; est-ce droite ? jr z, plus ; si oui aller a plus car ca incremente les pieces ld a, (inutil) ; *1 on verifie si inutil = 43 cp 43 ; est-ce qu'il vaut 43? ret nz ; si non on arrete jp z, choose_loop ; si oui alors on va a choose_loop plus: ; incremente le nombre de pieces ld a, (nombre_piece) ; met le nombre de pieces dans A cp 9 ; est-ce qu'il vaut 9 ? jp z, choose_loop ; si oui alors on retourne car trop grand inc a ; autrement on incremente A ld (nombre_piece), a ; on le remet dans nombre_piece jp print_nombre_piece ; on affiche la nouvelle valeur moins: ; decremente le nombre de pieces ld a, (nombre_piece) ; met le nombre_piece dans A cp 1 ; est-ce qu'il vaut 1 ? jp z, choose_loop ; si oui on repart car il est trop petit dec a ld (nombre_piece), a ; on le remet dans nombre_piece *3 print_nombre_piece: ; affiche le nombre de pieces choisies ld hl, $1F04 ; on veut l'afficher au 14eme rang 4eme ligne ld (_curRow), hl ; on met HL dans les positions du curseur ld a, (nombre_piece) ; met la valeur de nombre_piece dans A dec a ; retranche 1 ld hl, nombre ; met l'adresse de nombre dans HL call d_e_a ld a, (hl) ; met le symbole de l'adresse HL dans A ld hl, blank ; met l'adresse de blank dans HL ld (hl), a ; met le symbole de A dans blank call _puts ; affiche ce symbole jr choose_loop ; retourne a choose_loop start_game: ; met les setup start_setup: call variable ; on met les valeurs dans les variables call put_screen ; on affiche les trois tiges call put_piece ; on affiche les rondelles call put_curseur ; on place le curseur call put_score ; on affiche le score jp main_loop ; retour put_score: ; affiche le score au milieu du haut ld hl, 50 ; met 50 dans HL ld (_penCol), hl ; entre les coordonnes du curseur (50x;0y) ld hl, (time) ; met le score (time) dans HL call DispHL ; affcieh HL ret variable: ; initialise les variables ld a, $20 ; met le symbole " " dans blank (normal...!) ld hl, blank ; prend l'adresse de blank ld (hl), a ; met A dans cette adresse ld hl, $0000 ; HL = 0000 ld (time), hl ; score = 0 xor a ; 0 va dans A ld (inutil), a ; inutil = 0 ld hl, pile1 ; met a 0 les piles ld b, 27 ; il y a 27 adresses call var_loop ; met la loop pour affecter les valeurs ret ; on retourne var_loop: ; loop pour initialiser les piles (1, 2 et 3) ld (hl), a ; met 0 dans l'adresse HL inc hl ; incremente HL djnz var_loop ; decremente b verifie si il vaut 0 sinon va a var_loop ret ; autrement retourne au call put_screen: ; dessine l'ecran call _clrLCD call GraphBufClear ; nettoie le GraphBuffer ld b, 14 ; ] premier ld c, 10 ; ] en bas a gauche ld d, 38 ; ] ld e, 10 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 14 ; ] deuxieme ld c, 11 ; ] en bas a gauche ld d, 38 ; ] ld e, 11 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 52 ; ] premier ld c, 10 ; ] du milieu ld d, 76 ; ] ld e, 10 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 52 ; ] deuxieme ld c, 11 ; ] du milieu ld d, 76 ; ] ld e, 11 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 90 ; ] premier ld c, 10 ; ] a droite ld d, 114 ; ] ld e, 10 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 90 ; ] deuxime ld c, 11 ; ] a gauche ld d, 114 ; ] ld e, 11 ; ] ld h, 1 ; ] call _ILine ; ] pilier: ld b, 27 ; ] premier ld c, 10 ; ] pilier ld d, 27 ; ] ld e, 40 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 26 ; ] premier pilier ld c, 10 ; ] ld d, 26 ; ] ld e, 40 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 64 ; ] deuxieme pilier ld c, 10 ; ] ld d, 64 ; ] ld e, 40 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 65 ; ] deuxieme pilier ld c, 10 ; ] ld d, 65 ; ] ld e, 40 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 102 ; ] troisieme pilier ld c, 10 ; ] ld d, 102 ; ] ld e, 40 ; ] ld h, 1 ; ] call _ILine ; ] ld b, 103 ; ] troisieme pilier ld c, 10 ; ] ld d, 103 ; ] ld e, 40 ; ] ld h, 1 ; ] call _ILine ; ] ret ; on retourne GraphBufClear: ;Clears the graph buffer, so _ILine doesn't mess up (prise d'Ahmed El-Helw) ld hl,GRAPH_MEM ;GraphMem into HL ld (hl),0 ;Loads 0 into it ld de,GRAPH_MEM+1 ;Loads GraphMem+1 into de ld bc,1024 ;Loads the 1024 into bc ldir ;Draws on screen set graphdraw,(iy+graphflags) ;Sets Flag ret ;Return from Call put_piece: ; dessine les pieces ld a, 1 ; met 1 a A ld (h_value), a ; (h_value) vaut 1 ld a, (nombre_piece) ; met dans A le nombre de pieces add a, a ; *2 dec a dec a ; -2 ld hl, piece_value ; met dans HL l'adresse de piece_value call d_e_a ld a, (hl) ; met le contenu de l'adresse de HL dans A ld (pointX1), a ; met A dans pointX1 ld a, 11 ; A = 11 ld (pointY1), a ; met A dans pointY1 inc hl ; incremente HL ld a, (hl) ; remet le contenu de l'adresse de HL dans A ld (pointX2), a ; met A dans pointX2 ld a, (nombre_piece) ; met dans A le nombre de pieces ld b, a ; B = A piece_loop: ld hl, pointX1 ; met l'adresse de pointX1 dans HL inc (hl) ; incremente le contenu de l'adresse inc (hl) ; incremente le contenu de l'adresse ld hl, pointX2 ; met l'adresse de pointX2 dans HL dec (hl) ; decremente le contenu de l'adresse dec (hl) ; decremente le contenu de l'adresse ld hl, pointY1 ; met l'adresse de pointY1 dans HL inc (hl) ; incremente le contenu de l'adresse inc (hl) ; incremente le contenu de l'adresse call print_piece ; dessine la piece ld hl, pointY1 ; met l'adresse de pointY1 dans HL inc (hl) ; incremente call print_piece ; djnz piece_loop ; value_loop: ld hl, pile1 ld a, (nombre_piece) ld b, a popo: ld (hl), a dec a inc hl djnz popo ret print_piece: push bc ld a, (pointX1) ld b, a ld a, (pointY1) ld c, a ld e, a ld a, (pointX2) ld d, a ld a, (h_value) ld h, a call _ILine pop bc ret DispA: ;Routine to Display A [By: Matthew Shepcar] ld l,a ;Loads a into l ld h,0 ;0 into H DispHL: ;Displays HL [By: Matthew Shepcar] xor a ;Loads 0 into A ld de,-1 ;Loads -1 into DE ld (_curRow),de ;Loads de into CurRow call 4A33h ;Calls 4A33h dec hl ;Decrease it jp _vputs ;Put on screen and return d_e_a: ld d, 0 ld e, a add hl, de ret put_curseur: ld a, 1 ld (cur_position), a move_curseur: ld a, (cur_position) add a, a ld b, 2 sub b ld hl, cur_coordonnee call d_e_a ld a, (hl) ld (curX), a inc hl ld a, (hl) ld (curY), a call print_curseur ret print_curseur: ld a, (curY) ld e, a ld a, (curX) ld hl, cursor call PutSprite ret ;---------------------- ;|Sprite Routine [XOR] ;---------------------- ;------------------------------------------------------ ;|This Routine was converted by AVD from Movax's 83 ;|Special thanks to ScaBBy for making it XOR Routine! ;------------------------------------------------------ ;hl = image ;a = x coord ;e = y coord PutSprite: push hl ; Save sprite address ;лллл Calculate the address in graphbuf лллл ld hl,0 ; Do y*12 ld d,0 ex de,hl add hl,hl add hl,hl add hl,hl add hl,hl ld d,0 ; Do x/8 ld e,a srl e srl e srl e add hl,de ld de,$FC00 add hl,de ; Add address to graphbuf ld b,00000111b ; Get the remainder of x/8 and b cp 0 ; Is this sprite aligned to 8*n,y? jp z,ALIGN ;лллл Non aligned sprite blit starts here лллл pop ix ; ix->sprite ld d,a ; d=how many bits to shift each line ld e,8 ; Line loop LILOP: ld b,(ix+0) ; Get sprite data ld c,0 ; Shift loop push de SHLOP: srl b rr c dec d jp nz,SHLOP pop de ld a,b ; Write line to graphbuf xor (hl) ld (hl),a inc hl ld a,c xor (hl) ld (hl),a ld bc,15 ; Calculate next line address add hl,bc inc ix ; Inc spritepointer dec e jp nz,LILOP ; Next line jp DONE1 ;лллл Aligned sprite blit starts here лллл ALIGN: ; Blit an aligned sprite to graphbuf pop de ; de->sprite ld b,8 ALOP1: ld a,(de) xor (hl) ; xor=erase/blit ld (hl),a inc de push bc ld bc,16 add hl,bc pop bc djnz ALOP1 DONE1: ret ;мллллллллллллм SPRITE мллллллллллллллллллллллллллллллллллллллллллллллллллллллл cursor: .db %00000000 .db %00000000 .db %00011000 .db %00111100 .db %01100110 .db %11111111 .db %00011000 .db %00011000 ;-------------------------------------------- ;ллллллллллллллллллл GAME ллллллллллллллллллл ;-------------------------------------------- main_loop: call GET_KEY cp K_EXIT jp z, fin cp K_LEFT jp z, left cp K_RIGHT jp z, right cp K_SECOND jp z, seconde jp main_loop left: call print_curseur ld a, (cur_position) cp 1 call z, ex_gauche dec a ld (cur_position), a call move_curseur jp main_loop ex_gauche: ld a, 4 ret right: call print_curseur ld a, (cur_position) cp 3 call z, ex_droite inc a ld (cur_position), a call move_curseur jp main_loop ex_droite: xor a ret seconde: ld a, (cur_position) ld e, a add a, a ; *2 add a, a ; *4 add a, a ; *8 add a, e ; *9 ld b, 9 sub b ld hl, pile1 call d_e_a ld a, (hl) or a jp z, main_loop ld hl, $1300 ld (_curRow), hl ld hl, M call _puts take_loop: call GET_KEY cp K_EXIT jp z, fin cp K_LEFT jp z, left2 cp K_RIGHT jp z, right2 cp K_SECOND jp z, fin_move jp take_loop fin_move: ld hl, $1300 ld (_curRow), hl ld hl, blank call _puts jp main_loop ;---------------------------------- ;лллллллл BOUGER A GAUCHE ллллллллл ;---------------------------------- left2: call find ld (piece_prise), a ld a, (cur_hauteur2) ld (cur_hauteur), a ld a, (cur_position) ld (cur_position2), a ld hl, left_table dec hl call d_e_a ld a, (hl) ld (cur_position), a call find or a jp z, bon ld c, a ld a, (piece_prise) cp c jp m, bon ld a, (cur_position2) ld (cur_position), a jp take_loop find: ld a, (cur_position) ld hl, cur_table dec hl call d_e_a ld a, (hl) ld hl, pile1 call d_e_a xor a dec a ld (cur_hauteur2), a scearh_loop: ld a, (cur_hauteur2) inc a ld (cur_hauteur2), a ld a, (hl) or a jr z, found inc hl jp scearh_loop found: dec hl ld a, (hl) ret bon: ld a, (cur_position2) ; position en, mode "M" ld hl, cur_table dec hl call d_e_a ld a, (hl) ; A a une de ces valeurs: 0 9 18 ld hl, pile1 call d_e_a ld a, (cur_hauteur) dec a call d_e_a xor a ld (hl), a ld a, (cur_position2) dec a add a, a ; *2 ld e, a ; E = 2A add a, a ; *4 ld c, a ; C = 4A add a, a ; *8 add a, a ; *16 add a, a ; *32 add a, e ; *34 add a, c ; *38 ld e, 9 add a, e ld (pointX1), a ld e, 34 add a, e ld (pointX2), a ld a, (cur_hauteur) ld e, a add a, a add a, e ld e, 10 add a, e ld (pointY1), a xor a ld (h_value), a call print_piece ld a, (pointY1) inc a ld (pointY1), a call print_piece call pilier ; maintenant il faut remettre la rondelle ld a, (cur_position) ; nouvelle position ld hl, cur_table dec hl call d_e_a ld a, (hl) ; A a une de ces valeurs: 0 9 18 ld hl, pile1 call d_e_a ld a, (cur_hauteur2) ; = 0 call d_e_a ld a, (piece_prise) ld (hl), a ld a, (cur_position) dec a ld e, a add a, a ; *2 add a, a ; *4 add a, a ; *8 add a, a ; *16 add a, a ; *32 ld b, 6 puuu_loop: add a, e ; *38 djnz puuu_loop ld c, a ld hl, piece_value ld a, (piece_prise) cp 1 jr z, spe add a, a dec a dec a call d_e_a dec hl dec hl ld a, (hl) add a, c ld (pointX1), a inc hl ld a, (hl) add a, c ld (pointX2), a hauteur: ld a, (cur_hauteur2) inc a ld e, a add a, a add a, e ld e, 10 add a, e ld (pointY1), a ld a, 1 ld (h_value), a call print_piece ld a, (pointY1) inc a ld (pointY1), a call print_piece ld a, (cur_position2) ld (cur_position), a ld hl, (time) inc hl ld (time), hl call put_score jp check spe: ld a, 23 add a, c ld (pointX1), a ld a, 29 add a, c ld (pointX2), a jp hauteur ;---------------------------------- ;лллллллл BOUGER A DROITE ллллллллл ;---------------------------------- right2: call find ld (piece_prise), a ld a, (cur_hauteur2) ld (cur_hauteur), a ld a, (cur_position) ld (cur_position2), a ld hl, right_table dec hl call d_e_a ld a, (hl) ld (cur_position), a call find or a jp z, bon ld c, a ld a, (piece_prise) cp c jp m, bon ld a, (cur_position2) ld (cur_position), a jp take_loop fin: call _clrLCD ld hl, $0000 ld (_curRow), hl ret ;--------------------------------------- ;лллллллллллллллл TABLE лллллллллллллллл ;--------------------------------------- left_table: .db 3, 1, 2 right_table: .db 2, 3, 1 inutil: .db 0 pile1: .db 0,0,0,0,0,0,0,0,0 pile2: .db 0,0,0,0,0,0,0,0,0 pile3: .db 0,0,0,0,0,0,0,0,0 nombre: .db "1", "2", "3", "4", "5", "6", "7", "8", "9", 0 ;--------------------------------------- ;лллллллллллллллл STRING ллллллллллллллл ;--------------------------------------- combien: .db " combien d'anneaux ? " .db " " .db " <- -> ", 0 M: .db "M", 0 blank: .dB " ", 0 menustr: .db " The HANOI's TOWER " .db " " .db " by Alban Gervaise " .db " v0.1 ",0 bingostr: .db "!BINGO!", 0 ;--------------------------------------- ;ллллллллллллллл VARIABLE лллллллллллллл ;--------------------------------------- piece_prise: .db 0 piece_voulu: .db 0 cur_hauteur: .db 0 cur_hauteur2: .db 0 cur_position2: .db 0 cur_position: .db 0 cur_table: .db 0, 9, 18 pointX1: .db 0 pointX2: .db 0 pointY1: .db 0 piece_value: ; pointX1/pointY1/pointX2 .db 21,31 ; pour 1 .db 19,33 ; pour 2 .db 17,35 ; pour 3 .db 15,37 ; pour 4 .db 13,39 ; pour 5 .db 11,41 ; pour 6 .db 09,43 ; pour 7 .db 07,45 ; pour 8 .db 05,47 ; pour 9 cur_coordonnee: .db 23,55 ; en position 1 .db 61,55 ; en position 2 .db 99,55 ; en position 3 curX: .db 0 curY: .db 0 h_value: .db 0 time: .dw 0 nombre_piece: .db 0 ;----------------------------------------- ;лллллллллллллллл CHECK IT! лллллллллллллл ;----------------------------------------- check: ld hl, pile1 ld b, 18 check_loop: ld a, (hl) cp 0 jp nz, fin_move inc hl djnz check_loop ld hl, $0702 ld (_curRow), hl ld hl, bingostr call _puts call pause jp fin .end ; fin du programme ;*1: pourquoi ais-je mis ce nombre? En fait je ne sais pas pourquoi mais quand ;je demande le nombre de pieces sans demander verification du nombre, quand on ;quitte le jeu on revient a "choose_loop" sans en avoir l'instruction! Ainsi, ;j'ai mis 43 et a chaque boucle je demande si il vaut bien 43 (apres la boucle ;je met 0 dans inutile) pour ne pas avoir ce bug!!! ; ;*3: pas besoin de lui dire qu'il doit l'afficher car print_nombre_piece suit.