; ============================================================================= ; ; Litos8 display frame ; ; ============================================================================= ; ----------------------------------------------------------------------------- ; Exported user functions (7): ; DispFrameChar - display frame character ; DispFrameH - display horizontal frame line ; DispFrameV - display vertical frame line ; DispFrameHE - display horizontal frame line with edges ; DispFrameVE - display vertical frame line with edges ; DispFrame - display frame ; DispTable - display table frame ; ----------------------------------------------------------------------------- CODE_SECTION ; ----------------------------------------------------------------------------- ; Display frame character ; ----------------------------------------------------------------------------- ; INPUT: AL = mask (FRAME_H,...FRAME_B) ; AH = color attributes ; DL = column ; DH = row ; ----------------------------------------------------------------------------- ; ------------- push registers DispFrameChar: push ax ; push AX push bx ; push BX push cx ; push CX ; ------------- prepare frame mask -> BX and al,FRAME_MASK ; mask frame bits xor bx,bx ; BX <- 0 mov bl,al ; BX <- mask mov al,[bx+FrameCharTab] ; AL <- frame character call DispChar ; display character ; ------------- pop registers pop cx ; pop CX pop bx ; pop BX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Display horizontal frame line ; ----------------------------------------------------------------------------- ; INPUT: AL = mask (0 or FRAME_H) ; AH = color attributes ; CL = width (0...) ; DL = column ; DH = row ; ----------------------------------------------------------------------------- ; ------------- push registers DispFrameH: push ax ; push AX push bx ; push BX push cx ; push CX push dx ; push DX ; ------------- horizontal line mov ch,0 ; CH <- 0 jcxz DispFrameH8 ; invalid width xor bx,bx ; BX <- 0 and al,FRAME_H ; horizontal double flag or al,FRAME_L+FRAME_R ; left and right mov bl,al ; BX <- flags mov al,[bx+FrameCharTab] ; AL <- frame character DispFrameH2: call DispChar ; display character inc dl ; DL <- next column loop DispFrameH2 ; next character ; ------------- pop registers DispFrameH8: pop dx ; pop DX pop cx ; pop CX pop bx ; pop BX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Display vertical frame line ; ----------------------------------------------------------------------------- ; INPUT: AL = mask (0 or FRAME_V) ; AH = color attributes ; CH = height (0...) ; DL = column ; DH = row ; ----------------------------------------------------------------------------- ; ------------- push registers DispFrameV: push ax ; push AX push bx ; push BX push cx ; push CX push dx ; push DX ; ------------- vertical line mov cl,ch ; CL <- height mov ch,0 ; CH <- 0 jcxz DispFrameV8 ; invalid height xor bx,bx ; BX <- 0 and al,FRAME_V ; vertical double flag or al,FRAME_T+FRAME_B ; top and bottom mov bl,al ; BX <- flags mov al,[bx+FrameCharTab] ; AL <- frame character DispFrameV2: call DispChar ; display character inc dh ; DH <- next row loop DispFrameV2 ; next character ; ------------- pop registers DispFrameV8: pop dx ; pop DX pop cx ; pop CX pop bx ; pop BX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Display horizontal frame line with edges ; ----------------------------------------------------------------------------- ; INPUT: AL = mask (FRAME_H,...FRAME_B) ; AH = color attributes ; CL = width (0...) ; DL = column ; DH = row ; ----------------------------------------------------------------------------- ; ------------- push registers DispFrameHE: push ax ; push AX push bx ; push BX push cx ; push CX push dx ; push DX push si ; push SI ; ------------- prepare width -> CX mov ch,0 ; CH <- 0 jcxz DispFrameHE8 ; invalid width ; ------------- prepare frame mask -> BX, SI and al,FRAME_MASK ; AL <- frame mask xor bx,bx ; BX <- 0 mov bl,al ; BX <- mask mov si,bx ; SI <- save frame mask ; ------------- There is only 1 character dec cx ; width - 1 jz short DispFrameHE6 ; there is only 1 character ; ------------- left edge or bl,FRAME_R ; BX <- right flag mov al,[bx+FrameCharTab] ; AL <- frame character call DispChar ; display character inc dl ; DL <- next column ; ------------- horizontal line dec cx ; width - 1 jz short DispFrameHE4 ; there are only edges mov bx,si ; BX <- frame mask and bl,FRAME_H ; only horizontal double flag or bl,FRAME_L+FRAME_R ; BX <- left and right flags mov al,[bx+FrameCharTab] ; AL <- frame character DispFrameHE2: call DispChar ; display character inc dl ; DL <- next position loop DispFrameHE2 ; next character ; ------------- right edge DispFrameHE4: mov bx,si ; BX <- frame mask or bl,FRAME_L ; BX <- left flag DispFrameHE6: mov al,[bx+FrameCharTab] ; AL <- frame character call DispChar ; display character ; ------------- pop registers DispFrameHE8: pop si ; pop SI pop dx ; pop DX pop cx ; pop CX pop bx ; pop BX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Display frame ; ----------------------------------------------------------------------------- ; INPUT: AL = flags (FRAME_H,...FRAME_FILL) ; AH = color attributes ; CL = width (0...) ; CH = height (0...) ; DL = column ; DH = row ; NOTES: Use AL=0 for single frame or FRAME_DBL for double frame. ; ----------------------------------------------------------------------------- ; ------------- check size DispFrame: cmp cl,0 ; check width je short DispFrame9 ; invalid width cmp ch,0 ; check height je short DispFrame9 ; invalid height ; ------------- only horizontal line cmp ch,1 ; height = 1? je short DispFrameHE ; use only horizontal line ; ------------- only vertical line cmp cl,1 ; width = 1? je short DispFrameVE ; use only vertical line ; ------------- push registers push ax ; push AX push cx ; push CX push dx ; push DX ; ------------- top line (with edges) push ax ; push AX or al,FRAME_B ; bottom flag call DispFrameHE ; display top line pop ax ; pop AX inc dh ; DH <- new row ; ------------- left and right line (without edges) sub ch,2 ; CH <- height without edges jz short DispFrame4 ; invalid height call DispFrameV ; display left line add dl,cl ; DL <- right column + 1 dec dl ; DL <- right column call DispFrameV ; display right line inc dl ; DL <- right column + 1 sub dl,cl ; DL <- left column ; ------------- bottom line (with edges) DispFrame4: add dh,ch ; DH <- bottom row or al,FRAME_T ; add top neighbor call DispFrameHE ; display bottom line ; ------------- fill frame inside sub cl,2 ; CL <- width without edges jz short DispFrame6 ; no inner area or ch,ch ; check height jz short DispFrame6 ; no inner area test al,FRAME_FILL ; fill frame? jz short DispFrame6 ; no sub dh,ch ; DH <- inner row inc dx ; DL <- inner column mov al,32 ; AL <- space character call DispFill ; fill inner area ; ------------- pop registers DispFrame6: pop dx ; pop DX pop cx ; pop CX pop ax ; pop AX DispFrame9: ret ; ----------------------------------------------------------------------------- ; Display vertical frame line with edges ; ----------------------------------------------------------------------------- ; INPUT: AL = mask (FRAME_H,...FRAME_B) ; AH = color attributes ; CH = height (0...) ; DL = column ; DH = row ; ----------------------------------------------------------------------------- ; ------------- push registers DispFrameVE: push ax ; push AX push bx ; push BX push cx ; push CX push dx ; push DX push si ; push SI ; ------------- prepare height -> CX mov cl,ch ; CL <- height mov ch,0 ; CH <- 0 jcxz DispFrameVE8 ; invalid height ; ------------- prepare frame mask -> BX, SI and al,FRAME_MASK ; AL <- frame mask xor bx,bx ; BX <- 0 mov bl,al ; BX <- mask mov si,bx ; SI <- save frame mask ; ------------- There is only 1 character dec cx ; height - 1 jz short DispFrameVE6 ; there is only 1 character ; ------------- top edge or bl,FRAME_B ; BX <- bottom flag mov al,[bx+FrameCharTab] ; AL <- frame character call DispChar ; display character inc dh ; DH <- next row ; ------------- vertical line dec cx ; height - 1 jz short DispFrameVE4 ; there are only edges mov bx,si ; BX <- frame mask and bl,FRAME_V ; only vertical double flag or bl,FRAME_T+FRAME_B ; BX <- top and bottom flags mov al,[bx+FrameCharTab] ; AL <- frame character DispFrameVE2: call DispChar ; display character inc dh ; DH <- next row loop DispFrameVE2 ; next character ; ------------- bottom edge DispFrameVE4: mov bx,si ; BX <- frame mask or bl,FRAME_T ; BX <- top flag DispFrameVE6: mov al,[bx+FrameCharTab] ; AL <- frame character call DispChar ; display character ; ------------- pop registers DispFrameVE8: pop si ; pop SI pop dx ; pop DX pop cx ; pop CX pop bx ; pop BX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Display table frame ; ----------------------------------------------------------------------------- ; INPUT: AL = flags (0 or FRAME_FILL) ; AH = color attributes ; BX = table template ; 1 byte: number of columns NC (1..) ; NC bytes: columns internal width,B7=double line ; 1 byte: number or rows NR (1..) ; NR bytes: rows internal height, B7=double line ; DL = column ; DH = row ; NOTES: First column and row sets double flag to end line, too. ; ----------------------------------------------------------------------------- ; ------------- push registers DispTable: push ax ; push AX push bx ; push BX push cx ; push CX push dx ; push DX push si ; push SI push di ; push DI ; ------------- prepare row pointer -> SI xor cx,cx ; CX <- 0 mov cl,[bx] ; CX <- number of columns add cx,bx ; CX <- end of columns inc cx ; CX <- start of rows mov si,cx ; SI <- start of rows ; ------------- prepare row counter -> CH mov ch,[si] ; CH <- number of rows inc si ; SI <- first row inc ch ; CH <- number of rows + 1 ; ------------- prepare vertical flags -> AL and al,FRAME_FILL ; AL <- fill flag or al,FRAME_B ; AL <- no top lines DispTable2: dec ch ; row counter jnz short DispTable3 ; not last row mov cl,[bx] ; CX <- number of columns add cx,bx ; CX <- end of columns inc cx ; CX <- start of rows mov si,cx ; SI <- start of rows inc si ; SI <- first row mov ch,0 ; CH <- 0 and al,FRAME_FILL+FRAME_T ; delete bottom flag DispTable3: push ax ; push AX, flags ; ------------- horizontal line of one row push cx ; push CX push dx ; push DX mov ch,[si] ; CH <- row height and al,FRAME_FILL+FRAME_B+FRAME_T ; delete unused flags rol ch,1 ; CH <- horizontal double flag and ch,FRAME_H ; CH <- horizontal double flag or al,ch ; AL <- set horizontal flag mov di,bx ; DI <- columns mov ch,[di] ; CH <- number of columns or al,FRAME_R ; AL <- add right flag ; ------------- one cross character on horizontal line DispTable4: inc di ; DI <- next column mov cl,[di] ; CL <- column width rol cl,1 rol cl,1 ; CL <- FRAME_V flag and al,FRAME_FILL+FRAME_B+FRAME_T+FRAME_H+FRAME_L+FRAME_R and cl,FRAME_V ; CL <- FRAME_V flag or al,cl ; AL <- set FRAME_V flag call DispFrameChar ; display frame character inc dl ; DL <- next column ; ------------- horizontal line of one column mov cl,[di] ; CL <- column width and cl,7fh ; CL <- column width call DispFrameH ; display horizontal line add dl,cl ; DL <- next column or al,FRAME_L ; AL <- add left flag dec ch ; columns counter jnz short DispTable4 ; next row ; ------------- last cross on horizontal line mov cl,[bx+1] ; CL <- width of first column rol cl,1 rol cl,1 ; CL <- FRAME_V flag and al,FRAME_FILL+FRAME_B+FRAME_T+FRAME_H+FRAME_L and cl,FRAME_V ; CL <- FRAME_V flag or al,cl ; AL <- set FRAME_V flag call DispFrameChar ; display frame character pop dx ; pop DX pop cx ; pop CX inc dh ; DH <- next row ; ------------- stop looping rows or ch,ch ; last row? jz short DispTable8 ; last row ; ------------- vertical lines of one row push cx ; push CX push dx ; push DX mov ch,[si] ; CH <- row height and ch,7fh ; CH <- row height mov di,bx ; DI <- columns mov cl,[di] ; CL <- number of columns DispTable6: inc di ; DI <- next column push ax ; push AX mov al,[di] ; AL <- column width rol al,1 rol al,1 ; AL <- FRAME_V flag (B1) call DispFrameV ; display vertical line pop ax ; pop AX inc dl ; DL <- next column ; ------------- fill table inside test al,FRAME_FILL ; fill table? jz short DispTable7 ; no fill table push ax ; push AX push cx ; push CX mov cl,[di] ; CL <- column width and cl,7fh ; CL <- column width mov al,32 ; AL <- space character call DispFill ; fill table pop cx ; pop CX pop ax ; pop AX ; ------------- shift to next column DispTable7: push ax ; push AX mov al,[di] ; AL <- column width and al,7fh ; AL <- column width add dl,al ; DL <- shift column pop ax ; pop AX dec cl ; column counter jnz short DispTable6 ; next column ; ------------- last vertical line mov al,[bx+1] ; AL <- first column rol al,1 rol al,1 ; AL <- FRAME_V flag (B1) call DispFrameV ; display last vertival line pop dx ; pop DX add dh,ch ; DH <- next row pop cx ; pop CX ; ------------- next row pop ax ; pop AX, flags inc si ; SI <- next row or al,FRAME_T ; add top line flags jmp DispTable2 ; next row ; ------------- pop registers DispTable8: pop ax ; destroy AX, flags pop di ; pop DI pop si ; pop SI pop dx ; pop DX pop cx ; pop CX pop bx ; pop BX pop ax ; pop AX ret ; ----------------------------------------------------------------------------- ; Constant data ; ----------------------------------------------------------------------------- CONST_SECTION ; ------------- frame characters (IBM PC extension) ; IBM PC code page 437: http://en.wikipedia.org/wiki/Code_page_437 ; ; B0: horizontal double ; B1: vertikal double ; B2: left ; B3: right ; B4: top ; B5: bottom ; -| =| -|| =|| FrameCharTab: db 32, 32, 32, 32 ; no lines db 32, 32, 32, 32 ; left db 32, 32, 32, 32 ; right FrameCharTab2: db 196, 205, 196, 205 ; left, right db 32, 32, 32, 32 ; top db 217, 190, 189, 188 ; left, top db 192, 212, 211, 200 ; right, top db 193, 207, 208, 202 ; left, right, top db 32, 32, 32, 32 ; bottom db 191, 184, 183, 187 ; left, bottom db 218, 213, 214, 201 ; right, bottom db 194, 209, 210, 203 ; left, right, bottom db 179, 179, 186, 186 ; top, bottom db 180, 181, 182, 185 ; left, top, bottom db 195, 198, 199, 204 ; right, top, bottom db 197, 216, 215, 206 ; left, right, top, bottom