; --------------------------------------------------------------- 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 cyan A_FELT equ $20 ; paper green A_PT0 equ $66 ; points: bright yellow, bright red, on green A_PT1 equ $62 A_HUM equ $67 ; the player's checkers: white A_COMP equ $20 ; Gnubby's: black A_HUMB equ $4f ; on the bar A_COMPB equ $08 A_SIDE equ $07 ; paper black A_MSG equ $78 ; paper white A_SCORE equ $46 ; yellow on black A_MLEN equ $45 ; the match's length: cyan on black A_DIE equ $78 A_CUBE equ $4f ; the cube: white ink on the bar's blue A_DIEU equ $39 ; a die played: blue on grey A_DIEC equ $47 ; Gnubby's: white on black, as his checkers A_MASC equ $70 ; Gnubby: black on yellow A_TRAYH equ $47 A_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