Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Yeong

Pages: [1] 2 3 ... 276
1
Axe / Re: Tilemapping help
« on: February 04, 2019, 01:14:53 pm »
There is this.

Code: [Select]
prgmNAME | The code from the external program is parsed as if it completely replaced this command in the main program. (Similar to the C++ "include")
Personally I like putting data like sprites and tilemaps to appvar.

2
Grammer / RTEXT, the Grammer module
« on: February 02, 2019, 11:04:13 pm »
I ported my textbox program to a grammer module.

How to use it:

Code: [Select]
"5RTEXT->>DMS
>DMSTBOX(x1,y1,width,height,String_Pointer[,NextPage_Key, Skip_Key

With hook,
Code: [Select]
"5RTEXT->$
$TBOX(x1,y1,width,height,String_Pointer[,NextPage_Key, Skip_Key

3
ASM / Re: Working on Textbox program for asm
« on: January 31, 2019, 02:47:34 pm »
Finally, it is finished!

4
ASM / Re: Working on Textbox program for asm
« on: January 31, 2019, 01:25:16 pm »
This little project is nearing the end, and currently it is fully functional as intended, except for the failsafe part.
The "force exit after pressing [ON]" part doesn't work that well.
(It's the label "NextPageKey" that handles it, along with "HardExit" right after.)

What am I doing wrong here?


EDIT: It apparently wasn't wrong, but it was sometimes missing the input.
It is fixed now.

Code: [Select]
#include "ti83plus.inc"
.org $9D93
.db t2ByteTok,tAsmCmp
ld (8000h),sp ; This stores the stack pointer to spsave... for later dark ritual.
bcall(_RclAns)
dec a
ret nz ;quit if answer is non-list
ex de,hl
ld b,(hl)
inc hl
cp (hl)
ret nz
inc hl ; grabbed list size in b
ld a,b ;our list needs to be either 4 or 6 elements
cp 4
jr z,Pass
cp 6
ret nz
Pass:
ld ix,cX ;apparently I do need ix here because my HL DE BCs are used a lot
loopbtimes:
push bc
rst 20h ;rMov9ToOP1
push hl
bcall(_ConvOP1)
pop hl
ld (ix),a
inc ix
pop bc
djnz loopbtimes
;bcall(_ClrLCDFull)
call Resetrect
ld hl,StringData
rst 20h
rst 10h ;rFindSym
ret c ;quit if string is not found
ex de,hl
ld c,(hl) ;grab string size
inc hl
ld b,(hl)
inc hl
loop:
ld a,(hl)   ;Need to check if it is a two-byte token, later
push af   ;Save A for later
push hl
push bc
bcall(_Get_Tok_Strng)
ld hl,op3-1    ;point to the byte *before* the output characters.
push hl
inc hl
ld a,(hl)
cp 1bh ;check if string is Exponent E. E = original 8 delay
pop hl
jr nz,notDelay1 ;skip if not
ld a,8
ld (Delay),a
pop bc
pop hl
pop af
jr +_
NotDelay1:
push hl
inc hl
ld a,(hl)
cp 11h ;check if string is  -1. -1 = 16 Delay
pop hl
jr nz,notDelay2 ;skip if not
ld a,16
ld (Delay),a
pop bc
pop hl
pop af
jr +_
NotDelay2:
push hl
inc hl
ld a,(hl)
cp 12h ;check if string is ^2. ^2 = slowest 32
pop hl
jr nz,notDelay3 ;skip if not
ld a,32
ld (Delay),a
pop bc
pop hl
pop af
jr +_
NotDelay3:
push hl
inc hl
ld a,(hl)
cp 14h ;check if string is degree sign. deg = newline
pop hl
jr nz,notdegree ;skip if not degree sign
call Resetcur
pop bc
pop hl
pop af
jr +_
notdegree:
push hl
inc hl
ld a,(hl)
cp 15h ;check if string is radian sign. rad = resetrect
pop hl
jr nz,tokenloop ;skip if not radian sign
call NextPageKey
call Resetrect
pop bc
pop hl
pop af
jr +_
tokenloop:
push hl     ;save HL
push bc    ;and BC
call CheckXPos
pop bc
pop hl
inc hl   ;Need to increment first to get to the character since we started one byte behind
ld a,(hl)
bcall(_VPutMap)
push bc
ei
ld a,(Delay)
ld b,a
ld a,(843Fh)
ld c,a
ld a,(SkipKey)
cp c
jr nz,PauseTime
srl b
PauseTime:
call Waith
djnz PauseTime
pop bc
dec c
jr nz,tokenloop
pop bc
pop hl
pop af
bcall(_IsA2ByteTok) ;Check if it was a 2 byte token
jr nz,+_
inc hl  ;increment hl for next calc since token was 2 bytes
dec bc  ;decrement bc since token was 2 bytes
_:
cpi
jp pe,loop  ; pe is used to test if BC reached 0.
call NextPageKey
ret
Waith:
ei
halt
bit onInterrupt,(iy+onFlags)
ret z
HardExit:
ld sp,(8000h)
ret
NextPageKey:
ld a,(NPKey)
ld c,a
Sub1:
call Waith
ld a,(843Fh)
cp c
jr nz,Sub1
ret
CheckXPos:
ld (hl),1 ; Put size byte. This string should always be 1 byte long.
bcall(_SStringLength) ;This destroys all but HL
ld a,(penCol)
add a,b ; Grab the future penCol position
ld b,a
dec b
dec b
ld a,(mX)
cp b
ret nc
Resetcur:
ld a,(cX)
inc a ;if pencol > mX, change the cursor position
inc a ;to next line before writing
ld (penCol),a
ld a,(penRow)
add a,6
ld (penRow),a
ld b,a ;check the YPos
ld a,(mY)
sub 6
cp b ; test if penRow > mY
ret nc ; skip if penRow <= mY
call NextPageKey
call Resetrect
ret
Resetrect:
push hl;Long push list yeah but I'll remove some
push de;when I see that I don't need to save them
push bc;later on when I code more
push af;
ld a,(cX)
ld l,a ;start setting rect boundary
ld a,(cY)
ld h,a
ld a,(cX)
inc a
inc a
ld (penCol),a ;set cursor column
dec a
dec a
ld d,a
ld a,(width)
ld b,a
ld a,d
add a,b
dec a
ld e,a
dec a
dec a
ld (mX),a ;set max c-length for x
ld a,(cY)
inc a
ld (penRow),a ;set cursor row
dec a
ld d,a
ld a,(height)
ld b,a
ld a,d
add a,b
dec a
ld d,a
dec a
dec a
ld (mY),a ;set max c-length for y
bcall(_DrawRectBorderClear) ; y u destroi all me registers
pop af
pop bc
pop de
pop hl
ret
StringData:
.db StrngObj,tVarStrng,tStr1,0
cX:
.db 0
cY:
.db 0
width:
.db 0
height:
.db 0
mX:
.db 0
mY:
.db 0
NPKey:
.db 36h
SkipKey:
.db 30h
Delay:
.db 8

5
ASM / Re: Working on Textbox program for asm
« on: January 30, 2019, 10:17:08 pm »
All right I think it is almost finished.

Now it will auto advance to next line / reset to top line depends on if the text fit the box or not.
Using a degree sign (o) will force a newline and using a radian sign (r) will force a new box.
When the screen is paused due to transitioning to new box, press any key to continue.

Code: [Select]
#include "ti83plus.inc"
.org $9D93
.db t2ByteTok,tAsmCmp
bcall(_RclAns)
dec a
ret nz ;quit if answer is non-list
inc de
inc de ;oh look size is 2 bytes silly TI
ex de,hl
ld ix,cX ;apparently I do need ix here because my HL DE BCs are used a lot
ld b,4 ;list should have 4 numbers
loop4times:
push bc
rst 20h
push hl
bcall(_ConvOP1)
pop hl
ld (ix),a
inc ix
pop bc
djnz loop4times
bcall(_ClrLCDFull)
call Resetrect
ld hl,StringData
rst 20h;rMov9ToOP1
rst 10h;rFindSym
ret c;quit if string is not found
ex de,hl
ld c,(hl);grab string size
inc hl
ld b,(hl)
inc hl
loop:
ld a,(hl)   ;Need to check if it is a two-byte token, later
push af   ;Save A for later
push hl
push bc
bcall(_Get_Tok_Strng)
ld hl,op3-1    ;point to the byte *before* the output characters.
push hl
inc hl
ld a,(hl)
cp 14h ;check if string is degree sign. deg = newline
pop hl
jr nz,notdegree ;skip if not degree sign
call Resetcur
pop bc
pop hl
pop af
jr +_
notdegree:
push hl
inc hl
ld a,(hl)
cp 15h ;check if string is radian sign. rad = resetrect
pop hl
jr nz,tokenloop ;skip if not radian sign
bcall(_getKey)
call Resetrect
pop bc
pop hl
pop af
jr +_
tokenloop:
push hl     ;save HL
push bc    ;and BC
call CheckXPos
pop bc
pop hl
inc hl   ;Need to increment first to get to the character since we started one byte behind
ld a,(hl)
bcall(_VPutMap)
dec c
jr nz,tokenloop
pop bc
pop hl
pop af
bcall(_IsA2ByteTok) ;Check if it was a 2 byte token
jr nz,+_
inc hl  ;increment hl for next calc since token was 2 bytes
dec bc  ;decrement bc since token was 2 bytes
_:
cpi
jp pe,loop  ; pe is used to test if BC reached 0.
bcall(_getKey)
ret
CheckXPos:
ld (hl),1 ; Put size byte. This string should always be 1 byte long.
bcall(_SStringLength) ;This destroys all but HL
ld a,(penCol)
add a,b ; Grab the future penCol position
ld b,a
dec b
dec b
ld a,(mX)
cp b
ret nc
Resetcur:
ld a,(cX)
inc a ;if pencol > mX, change the cursor position
inc a ;to next line before writing
ld (penCol),a
ld a,(penRow)
add a,6
ld (penRow),a
ld b,a ;check the YPos
ld a,(mY)
sub 6
cp b ; test if penRow > mY
ret nc ; skip if penRow <= mY
bcall(_getKey)
call Resetrect
ret
Resetrect:
push hl;Long push list yeah but I'll remove some
push de;when I see that I don't need to save them
push bc;later on when I code more
push af;
ld a,(cX)
ld l,a ;start setting rect boundary
ld a,(cY)
ld h,a
ld a,(cX)
inc a
inc a
ld (penCol),a ;set cursor column
dec a
dec a
ld d,a
ld a,(width)
ld b,a
ld a,d
add a,b
dec a
ld e,a
dec a
dec a
ld (mX),a ;set max c-length for x
ld a,(cY)
inc a
ld (penRow),a ;set cursor row
dec a
ld d,a
ld a,(height)
ld b,a
ld a,d
add a,b
dec a
ld d,a
dec a
dec a
ld (mY),a ;set max c-length for y
bcall(_DrawRectBorderClear)
pop af
pop bc
pop de
pop hl
ret
StringData:
.db StrngObj,tVarStrng,tStr1,0
cX:
.db 0
cY:
.db 0
width:
.db 0
height:
.db 0
mX:
.db 0
mY:
.db 0

EDIT: Huge thanks to Zeda and Runer. I couldn't have made it this far if it weren't for them.

6
ASM / Re: Working on Textbox program for asm
« on: January 30, 2019, 06:15:52 pm »
So I got into some sort of problem.
From above, I added a rectangle drawing for the textbox and a little routine for moving cursor to next row when the program detects the end of the designated pixel limit (stored in mX)
However, this screenshot is the result I get.
I assume the problem lies somewhere in my CheckXPos part, but I can't seem to pinpoint where the problem is.


EDIT: Fixed. Apparently I needed size bytes before the string before I could use SStringLength. Fixed code.

Code: [Select]
#include "ti83plus.inc"
.org $9D93
.db t2ByteTok,tAsmCmp
bcall(_RclAns)
dec a
ret nz ;quit if answer is non-list
inc de
inc de ;oh look size is 2 bytes silly TI
ex de,hl
ld ix,cX ;apparently I do need ix here because my HL DE BCs are used a lot
ld b,4 ;list should have 4 numbers
loop4times:
push bc
rst 20h
push hl
bcall(_ConvOP1)
pop hl
ld (ix),a
inc ix
pop bc
djnz loop4times
bcall(_ClrLCDFull)
call Resetrect
ld hl,StringData
rst 20h;rMov9ToOP1
rst 10h;rFindSym
ret c;quit if string is not found
ex de,hl
ld c,(hl);grab string size
inc hl
ld b,(hl)
inc hl
loop:
ld a,(hl)
bcall(_IsA2ByteTok);Check if first token is 2 bytes z=two bytes
jr z, _
ld d,h
ld e,l
jr __
_:
ld d,h
ld e,l
inc hl;increase hl for next calc since token was 2-bytes
dec bc;decrease bc since token was 2-bytes
__:
push hl;need these for cpi
push bc;
ex de,hl
bcall(_Get_Tok_Strng)
ld hl,op3
tokenloop:
call CheckXPos
inc hl
ld a,(hl)
inc hl
bcall(_VPutMap)
dec c
jr nz,tokenloop
pop bc
pop hl
cpi
jp pe,loop; pe is used to test if BC reached 0.
bcall(_getKey)
ret
CheckXPos:
push de
push bc ; I should have hl as pointer for string still
dec hl
ld (hl),1 ; Put size byte. This string should always be 1 byte long.
bcall(_SStringLength) ;This destroys all but HL
ld d,a
ld a,(penCol)
add a,d ; Grab the future penCol position
push af
ld a,(mX)
ld d,a
pop af
inc d
cp d ; call Resetcur if pencol > mX
call nc,Resetcur
pop bc
pop de
ret
Resetcur:
ld a,(cX)
inc a ;if pencol > mX, change the cursor position
inc a ;to next line before writing
ld (penCol),a
ld a,(penRow)
add a,6
ld (penRow),a
ret
Resetrect:
push hl;Long push list yeah but I'll remove some
push de;when I see that I don't need to save them
push bc;later on when I code more
push af;
ld a,(cX)
ld l,a ;start setting rect boundary
ld a,(cY)
ld h,a
ld a,(cX)
inc a
inc a
ld (penCol),a ;set cursor column
dec a
dec a
ld d,a
ld a,(width)
ld b,a
ld a,d
add a,b
dec a
ld e,a
dec a
dec a
ld (mX),a ;set max c-length for x
ld a,(cY)
inc a
ld (penRow),a ;set cursor row
dec a
ld d,a
ld a,(height)
ld b,a
ld a,d
add a,b
dec a
ld d,a
dec a
dec a
ld (mY),a ;set max c-length for y
bcall(_DrawRectBorderClear)
pop af
pop bc
pop de
pop hl
ret
StringData:
.db StrngObj,tVarStrng,tStr1,0
cX:
.db 0
cY:
.db 0
width:
.db 0
height:
.db 0
mX:
.db 0
mY:
.db 0

7
ASM / Re: Working on Textbox program for asm
« on: January 30, 2019, 03:01:44 pm »
Now I can grab from both Str1 and Ans (that contains list of 4 numbers) correctly!

Code: [Select]
#include "ti83plus.inc"
.org $9D93
.db t2ByteTok,tAsmCmp
bcall(_RclAns)
dec a
ret nz ;quit if answer is non-list
inc de
inc de ;oh look size is 2 bytes silly TI
ex de,hl
ld ix,cX ;apparently I do need ix here because my HL DE BCs are used a lot
ld b,4 ;list should have 4 numbers
loop4times:
push bc
rst 20h
push hl
bcall(_ConvOP1)
pop hl
ld (ix),a
inc ix
pop bc
djnz loop4times
bcall(_ClrLCDFull)
ld hl,0
ld (penCol),hl
ld hl,StringData
rst 20h;rMov9ToOP1
rst 10h;rFindSym
ret c;quit if string is not found
ex de,hl
ld c,(hl);grab string size
inc hl
ld b,(hl)
inc hl
loop:
ld a,(hl)
bcall(_IsA2ByteTok);Check if first token is 2 bytes z=two bytes
jr z, _
ld d,h
ld e,l
jr __
_:
ld d,h
ld e,l
inc hl;increase hl for next calc since token was 2-bytes
dec bc;decrease bc since token was 2-bytes
__:
push hl;need these for cpi
push bc;
push de;
ex de,hl
bcall(_Get_Tok_Strng)
ld hl,op3
tokenloop:
ld a,(hl)
inc hl
bcall(_VPutMap)
dec c
jr nz,tokenloop
ld a,1
ld (curRow),a
ld (curCol),a
ld b,4
ld hl,cX
displaynum:
push hl
ld a,(hl)
ld h,0
ld l,a
bcall(_DispHL)
pop hl
inc hl
ld a,(curRow) ;because DispHL is not pretty
inc a
ld (curRow),a
ld a,0
ld (curCol),a
djnz displaynum
pop de
pop bc
pop hl
cpi
jp pe,loop; pe is used to test if BC reached 0.
bcall(_getKey)
ret
StringData:
.db StrngObj,tVarStrng,tStr1,0
cX:
.db 0
cY:
.db 0
width:
.db 0
height:
.db 0


8
ASM / Re: Working on Textbox program for asm
« on: January 30, 2019, 12:22:37 am »
Progress report:

Now the program converts tokens to ASCII and display them. This now takes care of my first priority of making the textbox: grabbing ASCIIs from Str1.

Code: [Select]
#include "ti83plus.inc"
.org $9D93
.db t2ByteTok,tAsmCmp
bcall(_ClrLCDFull)
ld hl,StringData
rst 20h;rMov9ToOP1
rst 10h;rFindSym
ret c;quit if string is not found
ex de,hl
ld c,(hl);grab string size
inc hl
ld b,(hl)
inc hl
loop:
ld a,(hl)
bcall(_IsA2ByteTok);Check if first token is 2 bytes z=two bytes
jr z, _
ld d,h
ld e,l
jr __
_:
ld d,h
ld e,l
inc hl;increase hl for next calc since token was 2-bytes
dec bc;decrease bc since token was 2-bytes
__:
push hl;need these for cpi
push bc;
push de;
ex de,hl
bcall(_Get_Tok_Strng)
ld hl,op3
ld a,(hl)
bcall(_VPutMap)
pop de
pop bc
pop hl
cpi
jp pe,loop; pe is used to test if BC reached 0.
bcall(_getKey)
ret
StringData:
.db StrngObj,tVarStrng,tStr1,0

9
ASM / Re: Working on Textbox program for asm
« on: January 29, 2019, 11:31:38 pm »
_Get_Tok_Str bcall
Oh.

I thought this meant it simply copies the token strings to OP3.
Now everything makes sense and the world feels a bit nicer again.

10
ASM / Re: Working on Textbox program for asm
« on: January 29, 2019, 09:25:58 pm »
So this was the work of yesterday. Now I know how to grab the Str1 and pull it up in the program.
(My original code was for just grabbing the first token of the string, but Zeda did her magic and suddenly the program started to show the whole string.)

Code: [Select]
#include "ti83plus.inc"
.org $9D93
.db t2ByteTok,tAsmCmp
bcall(_ClrLCDFull)
ld hl,StringData
rst 20h;rMov9ToOP1
rst 10h;rFindSym
ret c;quit if string is not found
ex de,hl
ld c,(hl);grab string size
inc hl
ld b,(hl)
inc hl
loop:
ld a,(hl)
bcall(_IsA2ByteTok);Check if first token is 2 bytes z=two bytes
jr z, _
ld d,0
ld e,(hl)
jr __
_:
ld d,(hl)
inc hl
dec bc;decrease bc since token was 2-bytes
ld e,(hl)
__:
push hl;need these for cpi
push bc;
bcall(_PutTokString)
pop bc
pop hl
cpi
jp pe,loop; pe is used to test if BC reached 0.
bcall(_getKey)
ret
StringData:
.db StrngObj,tVarStrng,tStr1,0

Today, I've been mostly doing some research on how to convert the token to a character.
One good thing is that I don't need to specify when the string will end since this way the loop will end when it reaches the end of the string.
Bad thing is that the only easy conversion is A-Z since their token values are same as the character values :P

I thought about doing some sort of lookup table until I realized that it is probably not a smart idea with 2 bytes tokens.
I looked through the bcalls but I didn't find anything that would help me do this.

I guess I could do bunch of CPs but that didn't sound that elegant.

What would be the best way to approach this problem?

11
Axe / Re: Alphabetize the VAT
« on: January 29, 2019, 04:04:43 pm »

12
ASM / Working on Textbox program for asm [Complete]
« on: January 28, 2019, 02:01:28 pm »
EDIT: Finished product here
https://www.omnimaga.org/asm-language/working-on-textbox-program-for-asm/msg406844/#msg406844

So, I decided that the best way to learn how to z80 is by coding small things.

Basically, I want to make a program that takes 4 variables from the list {Xinitial, Yinitial, Maximum rows of text, Maximum columns of text} and Str1, and draw a textbox out of it.
I wrote a pseudocode(?) for it so far.

Any comments or feedback is appreciated because I have no idea what I'm doing.

Code: [Select]
Get String from OS
Get X,Y coordinates
Get # of rows and cols
Store them to Coor

;Calc 2+maxX+4. Character is 4 pixels wide.
ld a,(tCol)
ld b,3
__:
add a,a
djnz __
add a,6
ld (mX),a
;now 2+maxY+6. Character is 6 pixels long.
ld a,(tRow)
ld b,5
___:
add a,a
djnz ___
add a,8
ld (mY),a

call DrawRect

;string starts at X+2,Y+2
call ResetLine
Put string length in bc

ld ix,String
;until it reads through all the text
Loop:
push bc ;save length
ld a,(mX)
cp (penCol)
call z,NextLine
ld a,(mY)
cp (penRow)
call z,ResetLine
ld a,(ix) ;now start checking characters
cp 'o' ;the degree sign - force cursor to next line
jr nz,Jump1
call NextLine
Jump1:
cp 'e^';e^ will make it wait for a keypress
jr nz,Jump2
call WaitForKey
Jump2:
ld (HChara),a
ld hl,HChara
bcall(_VPutS)
inc ix
call Delay ;force delay between texts
pop bc
dec bc
jr c, Loop ;if c is set, that means the loop went through all the text I think?

ret

DrawRect:
;Draw Rectangle at (X,Y,X+2+4*col,Y+2+6*row)
ld d,a
push de
;Something that clears inside the rect
ld l,(cX)
ld h,(cY)
ld a,(tCol)
sub 4
ld e,a
ld a,(tRow)
sub 6
ld d,a
bcall(_DrawRectBorder)
pop de
ld a,d
ret

NextLine:
ld d,a
ld a,(cX)
add a,2
ld (penCol),a
ld a,(penRow)
add a,6
ld (penRow),a
ld a,d
ret

ResetLine:
jr DrawRect
ld d,a
ld a,(cX)
inc a
inc a
ld (penCol),a
ld a,(cY)
inc a
inc a
ld (penRow),a
ld a,d
ret

Pause:
ld b,(Delay)
_:
nop
djnz _
ret

WaitForKey:
ld d,a
bcall(_getKey)
ld a,d
ret

Delay:
.db 40
cX:
.db x
cY:
.db y
tCol:
.db col
tRow:
.db row
mX:
.db 2+maxX+4
mY:
.db 2+maxY+6

HChara:
.db 0

EDIT: routine calls changed from jr to call.
Renamed variables for easier readability

13
ASM / Re: Number too large to fit?
« on: January 27, 2019, 09:07:26 pm »
Oof, just when I thought that I was no longer confusing (pointer) and pointer, I had it backwards.
The program worked as intended after the parenthesis. Thanks.

14
ASM / Number too large to fit?
« on: January 27, 2019, 08:33:39 pm »
So I have this.

Code: [Select]
#include "ti83plus.inc"
.org $9D93
.db t2ByteTok, tAsmCmp
bcall(_ClrLCDFull)
bcall(_getKey)
ld (Keystore),a
ld a,0
ld (curCol),a
ld (curRow),a
ld hl,Hello
bcall(_PutS)
ld a,1
ld (curRow),a
ld a,Keystore
ld h,0
ld l,a
bcall(_DispHL)
bcall(_getKey)
bcall(_ClrLCDFull)

ret
Hello:
.db "You pressed",0
Keystore:
.db 0

The compiler throws a warning at "ld a,Keystore" part, saying that the number is too big for 8-bit and is being truncated.
What am I doing wrong here?

15
Axe / Re: Quick Grayscale Tutorial
« on: January 24, 2019, 08:02:10 am »
As in the concept? Think of buffers as two sheets of semi-transparent papers stacked together. If something is located on the both sheets, it will look the darkest (black). If there is nothing on both sheets, well, then there won't be anything (white). For greys, things drawn only on the back sheet will look lighter than the things only drawn on the front sheet because the paper is semi-transparent, right?

Therefore
* drawn on both front and back - black
* drawn on neither - white
* drawn on front only - darker gray
* drawn on back only - lighter gray

Pages: [1] 2 3 ... 276