screen.asm
The board, checkers, dice, cube, Gnubby, the scores and what he says, drawn only where they change. Download · All the source
; --------------------------------------------------------------- screen; The board: points 13-24 along the top, 12-1 along the bottom (the; player's home at the bottom right), two columns a point, each point's; number on its base while it is empty, the bar in the middle (with the; cube, in the middle or at its owner's end); beside it Gnubby's score and; checkers borne off, Gnubby, the match's length, and the player's; checkers borne off and score; what Gnubby says in the two rows along the; bottom.A_FRAME equ $0d ; paper blue, ink cyanA_FELT equ $20 ; paper greenA_PT0 equ $66 ; points: bright yellow, bright red, on greenA_PT1 equ $62A_HUM equ $67 ; the player's checkers: whiteA_COMP equ $20 ; Gnubby's: blackA_HUMB equ $4f ; on the barA_COMPB equ $08A_SIDE equ $07 ; paper blackA_MSG equ $78 ; paper whiteA_SCORE equ $46 ; yellow on blackA_MLEN equ $45 ; the match's length: cyan on blackA_DIE equ $78A_CUBE equ $4f ; the cube: white ink on the bar's blueA_DIEU equ $39 ; a die played: blue on greyA_DIEC equ $47 ; Gnubby's: white on black, as his checkersA_MASC equ $70 ; Gnubby: black on yellowA_TRAYH equ $47A_TRAYC equ $42; scr: B = row, C = column -> HL = the cell's top pixel line.scr: ld a,b and $18 or $40 ld h,a ld a,b and 7 rrca rrca rrca or c ld l,a ret; att: B = row, C = column -> HL = the cell's attribute.att: ld a,b rrca rrca rrca ld l,a and 3 or $58 ld h,a ld a,l and $e0 or c ld l,a ret; putg: DE -> 8 bytes, B, C = a cell, A = its attribute: drawn there.; Keeps BC; DE after the 8 bytes.putg: push af call scr push bc ld b,8.l: ld a,(de) ld (hl),a inc de inc h djnz .l pop bc call att pop af ld (hl),a ret; putc: A = a character, B, C = a cell, in TATTR's colours. Keeps BC.putc: sub 32 ld l,a ld h,0 add hl,hl add hl,hl add hl,hl ld de,FONT add hl,de ex de,hl ld a,(TATTR) jr putg; print: HL -> text (| a new line, 0 the end), B, C = where. B, C left; after it.print: ld a,c ld (PCOL),a.l: ld a,(hl) inc hl or a ret z cp '|' jr nz,.c inc b ld a,(PCOL) ld c,a jr .l.c: push hl call putc pop hl inc c jr .l; fill: B, C = a corner, D rows by E columns of attribute A (and the; pixels cleared).fill: ld (FATTR),a.r: push bc push de.c: push bc call scr xor a push bc ld b,8.p: ld (hl),a inc h djnz .p pop bc call att ld a,(FATTR) ld (hl),a pop bc inc c dec e jr nz,.c pop de pop bc inc b dec d jr nz,.r ret; cls: the whole screen blank, black.cls: ld hl,$4000 ld de,$4001 ld bc,6143 ld (hl),l ldir inc hl inc de ld bc,767 ld (hl),A_SIDE ldir ret; pcol: A = the player's point index (0-23) -> C = its column; carry for; a top point.pcol: cp 6 jr nc,.a add a,a neg add a,25 ld c,a or a ret.a: cp 12 jr nc,.b add a,a neg add a,23 ld c,a or a ret.b: cp 18 jr nc,.c add a,a sub 23 ld c,a scf ret.c: add a,a sub 21 ld c,a scf ret; drawall: the whole board.drawall: ld a,(UP) or a call z,setup xor a.pt: push af call drawpt pop af inc a cp 24 jr nz,.pt call drawbar call drawtray call drawcube call drawdice call drawmasc call drawscore call hilite ld a,(SAIDNEW) or a ret z jp resay; setup: the board's frame and felt on a clear screen, and everything; else to be drawn: the rest of drawall only draws over what is there,; and what has not changed not at all, so nothing flickers.setup: ld a,1 ld (UP),a ld (SAIDNEW),a ld a,$ff ld hl,LSHOWN ld b,10.m: ld (hl),a inc hl djnz .m call cls ld bc,0 ld de,22*256+28 ld a,A_FRAME call fill ld bc,1 ld de,22*256+12 ld a,A_FELT call fill ld bc,15 ld de,22*256+12 ld a,A_FELT jp fill; drawpt: A = a point index: its triangle and number.drawpt: ld (TMPI),a ; its checkers: the player's, or Gnubby's ld hl,GB call index ld d,A_HUM or a jr nz,.some ld a,(TMPI) ld b,a ld a,23 sub b ld hl,GB+32 call index ld d,A_COMP.some: ld (SN),a ld a,d ld (SATT),a ld a,(SN) cp 5 jr c,.n ld a,5.n: add a,a ld (NCK),a ld a,(TMPI) call pcol ld a,0 rla ld (TOPPT),a ld a,(TMPI) and 1 ld a,A_PT0 jr z,.col ld a,A_PT1.col: ld (FATTR),a ld a,(NCK) ; the cells beyond the checkers ld e,a cp 10 jr z,.stk.k: push de ld a,e add a,a add a,a add a,a add a,a ld l,a ld h,0 ld de,TRI add hl,de ; its first line, from the base ex de,hl pop hl push hl ld a,(TOPPT) or a ld a,l jr z,.bot ld b,a ld hl,2 jr .draw.bot: neg add a,21 ld b,a ld hl,14 add hl,de ex de,hl ld hl,-2.draw: ld (TSTEP),hl push bc call scr ld b,8.ln: ld a,(de) ld (hl),a inc de inc l ld a,(de) ld (hl),a dec de dec l inc h push hl ld hl,(TSTEP) add hl,de ex de,hl pop hl djnz .ln pop bc call att ld a,(FATTR) ld (hl),a inc l ld (hl),a pop de inc e ld a,e cp 10 jr nz,.k.stk: ; the checkers, from the edge ld a,(TMPI) call pcol ld b,0 ld a,2 jr c,.top ld b,20 ld a,-2.top: ld (SDIR),a ld a,5 call stack ; the number, in small digits cut out of the point's base, if ; no checker covers it ld a,(NCK) or a ret nz ld a,(TMPI) call pcol ld b,0 jr c,.nb ld b,21.nb: ld a,(TMPI) add a,a add a,a ld l,a ld h,0 add hl,hl add hl,hl ld de,PTNUM add hl,de ex de,hl call xorg inc c; xorg: DE -> 8 bytes, B, C = a cell: XORed into its pixels. Keeps BC; DE; after the 8 bytes.xorg: push bc call scr ld b,8.l: ld a,(de) xor (hl) ld (hl),a inc de inc h djnz .l pop bc ret; drawbar: the checkers on the bar, 2 shown each (then the count): Gnubby's; from row 6 down, the player's from row 14 up; the cells without, blank.; And the pip counts (drawpips).drawbar: call drawpips ld a,(GB+32+24) ld (SN),a cp 2 jr nc,.c add a,a ld d,a add a,6 ld b,a ; from row 6 + 2n ld a,4 sub d ld d,a ; 4 - 2n rows ld e,2 ld c,13 ld a,A_FRAME call fill.c: ld a,A_COMPB ld (SATT),a ld a,2 ld (SDIR),a ld bc,6*256+13 ld a,2 call stack ld a,(GB+24) ld (SN),a cp 2 jr nc,.h add a,a ld d,a ld a,4 sub d ld d,a ; 4 - 2n rows from row 12 ld e,2 ld bc,12*256+13 ld a,A_FRAME call fill.h: ld a,A_HUMB ld (SATT),a ld a,-2 ld (SDIR),a ld bc,14*256+13 ld a,2 jp stack; drawpips: each side's pip count, under "PIP", in small digits on the bar:; Gnubby's at the top, the player's at the bottom; or (PIPOFF, the I key); none.drawpips: ld a,(PIPOFF) or a jr z,.on ld bc,13 ld de,2*256+2 ld a,A_FRAME call fill ld bc,20*256+13 ld de,2*256+2 ld a,A_FRAME jp fill.on: ld bc,13 call pipword ld hl,GB+32 call pips ld bc,1*256+13 call smallnum ld bc,20*256+13 call pipword ld hl,GB call pips ld bc,21*256+13 jp smallnum; pipword: "PIP" in small letters in the two cells at B, C.pipword: ld a,10 ld (DIG3),a ld (DIG3+2),a inc a ld (DIG3+1),a jr smalldraw; pips: HL -> a side's 25 points -> HL = its pip count.pips: push hl pop ix ld hl,0 ld de,1 ld b,25.p: ld a,(ix+0).a: or a jr z,.n add hl,de dec a jr .a.n: inc ix inc de djnz .p ret; smallnum: HL (0-999) in small digits, right-aligned in the two cells at; B, C, in the frame's colours. Each character 3 dots wide and 5 high, at; dots 2, 6 and 10 of the 16: the digits, then P (10) and I (11).smallnum: push bc ld de,NUMBUF call utoa ; HL left at the 0 after the digits ex de,hl ld de,DIG3+2 ld b,3.d: ld a,l or a ; NUMBUF starts a page ld a,12 ; none jr z,.s dec hl ld a,(hl) sub '0'.s: ld (de),a dec de djnz .d pop bc; smalldraw: DIG3's three small characters in the two cells at B, C.smalldraw: push bc call scr xor a ld (SLINE),a.ln: push hl ld de,0 ld a,(SLINE) dec a cp 5 jr nc,.put ld (SROW),a ld a,(DIG3) call srow ld d,a ld a,(DIG3+1) call srow add a,a add a,a add a,a add a,a ld e,a ld a,(DIG3+2) call srow or e ld e,a ex de,hl add hl,hl add hl,hl add hl,hl ex de,hl.put: pop hl ld (hl),d inc l ld (hl),e dec l inc h ld a,(SLINE) inc a ld (SLINE),a cp 8 jr nz,.ln pop bc call att ld (hl),A_FRAME inc l ld (hl),A_FRAME ret; srow: A = a small character (12 for none) -> A = its row SROW, three; dots.srow: cp 12 jr c,.d xor a ret.d: ld l,a add a,a add a,a add a,l ld l,a ld a,(SROW) add a,l ld hl,SDIG jp index; stack: SN checkers in SATT from B, C (each two cells by two, from its; top left), SDIR rows apart, at most A shown (the last with the count cut; out of it if more).stack: ld (SMAX),a ld a,(SN) or a ret z ld e,a ld d,0.k: inc d push de ld a,d ld hl,SMAX cp (hl) ld a,0 jr nz,.chk ld a,e ; the last shown: the count, if more cp d jr nz,.chk xor a.chk: ld l,a ; CHK + 32 x (0 or the count) ld h,0 add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ld de,CHK add hl,de ex de,hl ld a,(SATT) call putg inc c call putg inc b dec c call putg inc c call putg dec b dec c ld a,(SDIR) add a,b ld b,a pop de ld a,d cp e ret z ld hl,SMAX cp (hl) jr nz,.k ret; num2: A (up to 99) in two cells at B, C in TATTR's colours.num2: ld e,'0'-1.t: inc e sub 10 jr nc,.t add a,10+'0' push af ld a,e cp '0' jr nz,.d ld a,' '.d: call putc inc c pop af jp putc; drawtray: the checkers borne off, as stripes.drawtray: ld hl,GB+32 call total ld d,a ld hl,GB call total ld e,a ld hl,(LTRAY) ld a,l cp d jr nz,.go ld a,h cp e ret z.go: ld l,d ld h,e ld (LTRAY),hl ld bc,1*256+29 ld de,6*256+2 ld a,A_TRAYC call fill ld bc,15*256+29 ld de,6*256+2 ld a,A_TRAYH call fill ld hl,GB+32 call total neg add a,15 ld b,a ld a,8 ld e,3 call stripes ld hl,GB call total neg add a,15 ld b,a ld a,166 ld e,-3; stripes: B checkers, from pixel line A by E each.stripes: inc b.s: dec b ret z push af push bc push de ld c,29 call pixaddr ld a,$3f ld (hl),a inc l ld (hl),$fc pop de pop bc pop af push af inc a push bc push de ld c,29 call pixaddr ld (hl),$7f inc l ld (hl),$fe pop de pop bc pop af add a,e jr .s; pixaddr: A = a pixel line, C = a column -> HL.pixaddr: ld b,a and 7 or $40 ld h,a ld a,b and $c0 rrca rrca rrca or h ld h,a ld a,b and $38 rlca rlca or c ld l,a ret; drawcube: the cube, by its owner: Gnubby above, the middle, the player; below.drawcube: ld hl,LCUBE ld a,(OWNER) cp (hl) jr nz,.new inc hl ld a,(CUBE) cp (hl) jr nz,.new inc hl ld a,(CRAW) cp (hl) ret z.new: ld a,(OWNER) ld (LCUBE),a ld a,(CUBE) ld (LCUBE+1),a ld a,(CRAW) ld (LCUBE+2),a ld bc,3*256+13 ; its three places on the bar cleared call .clr ld bc,10*256+13 call .clr ld bc,17*256+13 call .clr ld bc,14*256+28 ; and CRAW beside the board ld de,1*256+4 ld a,A_SIDE call fill ld a,(MLEN) or a jr z,.go ld a,(CRAW) dec a jr nz,.go ld bc,14*256+28 ; no cube in the Crawford game ld a,A_MLEN ld (TATTR),a ld hl,S_CRAW jp print.go: ld a,(OWNER) ; in the middle, or at its owner's end ld b,10 or a jr z,.r ld b,17 dec a jr z,.r ld b,3.r: ld c,13 ld a,(CUBE) ; its face: the cube's log 2 ld e,-1.l: inc e srl a jr nz,.l ld l,e ld h,0 add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ld de,CUBEG add hl,de ex de,hl ld a,A_CUBE jp put4.clr: ld de,2*256+2 ld a,A_FRAME jp fill; drawdice: the dice rolled (SHOWN: 1 the player's, 2 Gnubby's, 3 one; each to open).drawdice: ld a,(SHOWN) ld hl,LSHOWN cp (hl) jr z,.keep ld (hl),a ld bc,10*256+1 ld de,2*256+12 ld a,A_FELT call fill ld bc,10*256+15 ld de,2*256+12 ld a,A_FELT call fill.keep: ld a,(SHOWN) or a ret z cp 3 jr nz,.two ld a,(DIE1) ld bc,10*256+20 ld e,A_DIE call die ld a,(DIE2) ld bc,10*256+6 ld e,A_DIEC jr die.two: dec a ld c,18 jr z,.h ld c,4 ld e,A_DIEC ld a,(DIE1) ld b,10 push bc call die pop bc ld a,c add a,3 ld c,a ld e,A_DIEC ld a,(DIE2) jr die.h: ; used or not push bc ld a,(DIE1) ld b,a ld a,(DIE2) cp b jr z,.dbl ld a,(U1) call used ld a,(DIE1) ld b,10 call die ld a,(U2) call used jr .d2.dbl: ld a,(NMAX) ld hl,NDONE sub (hl) cp 3 ccf sbc a,a inc a call used ld a,(DIE1) ld b,10 call die ld a,(NMAX) ld hl,NDONE sub (hl) cp 1 ccf sbc a,a inc a call used.d2: pop bc ld a,c add a,3 ld c,a ld b,10 ld a,(DIE2); die: A = its face, B, C = where, E = its attribute.die: dec a add a,a add a,a add a,a add a,a add a,a ld l,a ld h,0 push de ld de,DICE add hl,de ex de,hl pop hl ld a,l; put4: DE -> 32 bytes, B, C = a corner, A = the attribute: two cells by; two drawn there.put4: call putg inc c call putg dec c inc b call putg inc c jp putg; used: A nonzero if played -> E = the die's attribute. Keeps BC.used: or a ld e,A_DIE ret z ld e,A_DIEU ret; drawmasc: Gnubby, in his mood, beside the board.drawmasc: ld bc,8*256+28; mascot: Gnubby in MOOD at B, C.mascot: ld a,(MOOD) ld l,0 srl a rr l ld h,a ; x 128 ld de,MASC add hl,de ex de,hl ld l,4.r: push bc ld h,4.c: push hl ld a,A_MASC call putg pop hl inc c dec h jr nz,.c pop bc inc b dec l jr nz,.r ret; drawscore: the scores, and the match's length.drawscore: ld hl,LSCORE ld a,(SCH) cp (hl) jr nz,.new inc hl ld a,(SCC) cp (hl) jr nz,.new inc hl ld a,(MLEN) cp (hl) jr nz,.new inc hl ld a,(CRAW) cp (hl) ret z.new: ld a,(SCH) ld (LSCORE),a ld a,(SCC) ld (LSCORE+1),a ld a,(MLEN) ld (LSCORE+2),a ld a,(CRAW) ld (LSCORE+3),a ; beside the board: Gnubby's at the top, the player's at the ; bottom, and the match's length above the player's tray ld bc,28 ld de,1*256+4 ld a,A_SCORE call fill ld bc,21*256+28 ld de,1*256+4 ld a,A_SCORE call fill ld bc,13*256+28 ld de,1*256+4 ld a,A_SIDE call fill ld a,A_SCORE ld (TATTR),a ld hl,(SCC) ld b,0 call rnum ld hl,(SCH) ld b,21 call rnum ld a,(MLEN) or a ret z ld a,A_MLEN ld (TATTR),a ld bc,13*256+28 ld hl,S_TO call print ld a,(MLEN) ld l,a ld h,0; pnum: HL printed in decimal at B, C.pnum: push bc ld de,NUMBUF call utoa pop bc ld hl,NUMBUF jp print; rnum: HL printed in decimal in row B, ending at the screen's edge.rnum: push bc ld de,NUMBUF call utoa pop bc ld a,32 ; NUMBUF starts a page: E is the length sub e ld c,a ld hl,NUMBUF jp print; utoa: HL in decimal at DE, ended by 0; DE left at the 0.utoa: xor a ld (UZERO),a ld bc,-10000 call .d ld bc,-1000 call .d ld bc,-100 call .d ld bc,-10 call .d ld a,l add a,'0' ld (de),a inc de xor a ld (de),a ret.d: ld a,'0'-1.s: inc a add hl,bc jr c,.s sbc hl,bc cp '0' jr nz,.w ld a,(UZERO) or a ret z ld a,'0'.w: ld (de),a inc de ld (UZERO),a ret; hilite: the point under the cursor flashing, while the player moves.hilite: ld a,(CURS) cp 25 ret nc cp 24 ld bc,14*256+13 jr z,.two call pcol ; the base's two rows ld b,0 jr c,.two ld b,20.two: call .fl inc b.fl: call att set 7,(hl) inc l set 7,(hl) ret; say: HL -> what Gnubby says, into the speech area (kept for redrawing).say: ld de,SAID.cp: ld a,(hl) ld (de),a inc hl inc de or a jr nz,.cp; resay: what Gnubby said, written over the last, each line padded with; spaces to the edge (rather than cleared first, which would flicker).resay: xor a ld (SAIDNEW),a ld a,A_MSG ld (TATTR),a ld hl,SAID ld b,22.row: ld c,0 ld a,' ' call putch inc c.ch: ld a,(hl) or a jr z,.pad inc hl cp '|' jr z,.pad call putch inc c ld a,c cp 32 jr c,.ch.pad: ld a,c cp 32 jr nc,.next ld a,' ' call putch inc c jr .pad.next: inc b ld a,b cp 24 jr c,.row ret; TICK: from the engine, before each of the opponent's rolls it tries:; the dots after the first line of what Gnubby says, one more each time; (none after three), to show he is still thinking. Keeps the registers.TICK: push af push bc push de push hl ld a,(DOTS) inc a and 3 ld (DOTS),a ld e,a ld hl,SAID ; the first line's end ld c,1.end: ld a,(hl) or a jr z,.dots cp '|' jr z,.dots inc hl inc c jr .end.dots: ld a,A_MSG ld (TATTR),a ld b,22 ld d,3.d: ld a,c cp 32 jr nc,.x ld a,'.' dec e jp p,.put ld a,' '.put: push de call putc pop de inc c dec d jr nz,.d.x: pop hl pop de pop bc pop af ret; putch: putc, keeping HL.putch: push hl call putc pop hl ret; bigtext: HL -> text, B, C = where: letters twice the size, each its own; colour.bigtext: ld a,(hl) or a ret z inc hl push hl push bc call bigc pop bc inc c inc c ld a,(TATTR) inc a and 7 jr nz,.k ld a,2.k: or $40 ld (TATTR),a pop hl jr bigtext; bigc: A = a character at B, C, doubled.bigc: sub 32 ld l,a ld h,0 add hl,hl add hl,hl add hl,hl ld de,FONT add hl,de ex de,hl call .half inc b.half: push bc call scr ld b,4.row: ld a,(de) inc de push de push hl push bc call dbl pop bc pop hl ld (hl),d inc l ld (hl),e inc h ld (hl),e dec l ld (hl),d inc h pop de djnz .row pop bc call att ld a,(TATTR) ld (hl),a inc l ld (hl),a ret; dbl: A's bits each doubled -> D, E.dbl: ld c,a ld de,0 ld b,8.l: sla e rl d sla e rl d sla c jr nc,.n ld a,e or 3 ld e,a.n: djnz .l ret