Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- cpu 286
- org 100h
- RowSz equ 80
- BankSz equ 8192
- %define _FontSeg 0xCCCC
- %define _FontPtr 0x9090
- %define _DrawRow bp+(6+18+0)
- %define _DrawCol bp+(6+18+2)
- %define _TextSeg bp+(6+18+4)
- %define _TextPtr bp+(6+18+6)
- %define _TextLen bp+(6+18+8)
- section .text
- DrawString:
- pusha
- push ds
- push es
- ;-----------------------------------------------------------------------------------------
- call SelfPtr ;\
- SelfPtr: ;<PIPE>
- pop bx ;<PIPE>
- sub bx, SelfPtr ;<PIPE> auto fix-up pointers...
- add [cs:bx+SelfW1-2],bx ;<PIPE>
- add [cs:bx+SelfW2-2],bx ;<PIPE>
- add [cs:bx+SelfW3-3],bx ;<PIPE>
- add [cs:bx+SelfW4-3],bx ;/
- mov word [cs:bx+SelfPtr-3],(((Start-SelfPtr)*256)+0E9h) ; Call SelfPtr -> Jmp Start
- ;-----------------------------------------------------------------------------------------
- Start:
- mov ax,[_DrawRow] ; Get Start ROW
- mov bx, ax ; \
- shl ax, 8 ; <PIPE> BX = ROWS*RowSz*4
- shl bx, 6 ; <PIPE> ( 320 = 2^8 + 2^6 )
- add bx, ax ; /
- mov ax,[_DrawCol] ; Get Start COLUMN
- mov cl, al ; copy Of COL
- and cl, 3 ; which mode it starts?
- add cl, cl ; start of shift2
- mov ch, 8 ; start of shift1 is..
- sub ch, cl ; 8-shift2...
- mov byte [CS:SelfModB1-1], ch ;self-mod "shr bh, #"
- SelfW1:
- mov si, ax ; another copy for start offset
- add si, si ; 2 bytes per char
- shr ax, 2 ; minus 1 byte
- add si, ax ; for each 4 characters...
- mov es,[_TextSeg] ;ES = text source segment
- mov di,[_TextPtr] ;ES:DI = text source (could be CS/ES for multisegment)
- mov ch,[_TextLen] ;CH = text length
- ; ## NO MORE LOCAL VARIABLES AFTER THIS POINT ###########################################
- lea bp,[si+bx] ;SS:BP screen target (for BP relative)
- mov dx,BankSz ;Switch Between Banks or between liens (alternates)
- push SS ;Save current stack segment on stack
- pop word [CS:SelfModW1-2] ;And pop it on self-modified var for restoration
- SelfW2:
- mov ax,_FontSeg ; font segment (Modified on ARRAY)
- ModW1:
- mov ds,ax ; DS = Font Segment
- mov ax,0xB800 ; SS = screen target
- cli ; Disabling interrupts because SS will be modified
- mov ss,ax ; and screen becomes SS (for bp+ usage)
- NextChar:
- dec ch ; Any chars remaining?
- js DoneDraw ; No? then it's done...
- xor bx,bx ; clear BX (for byte->word cast)
- mov bl,[es:di] ; BL = next char
- inc di ; point to next source char :)
- shl bx, 4 ; 16 bits * 8 rows = 16bytes
- lea si,[bx+_FontPtr] ; DS:SI font (for lodsw) (Modified on ARRAY)
- ModW2:
- mov bl,8 ; 8 rows
- DrawChar:
- lodsw ; read a char line (16 bits)
- mov bh,ah ; need part of it for a byte
- shr bh,7 ; shr by 8,6,4,2 (self-modified...)
- SelfModB1:
- jz SkipByte ; the result is 0? so no pixels to set
- or [bp-1],bh ; merge with screen
- SkipByte:
- shl ax,cl ; shl by 0,2,4,6 (0 ignores flags)
- test ax,ax
- jz SkipWord ; the result is 0? so no pixels to set
- xchg ah,al ; must change endian...
- or [bp],ax ; and merge with screen
- SkipWord:
- add bp, dx ; change to next line
- xor dx, ((-BankSz)^BankSz)+RowSz ; line/block swap
- dec bl ; one line done, there's more?
- jnz DrawChar ; yes, go draw them
- AfterChar:
- sub bp,RowSz*4-2 ; adjust to next char
- add cl, 2 ; \ 0 -> 2 -> 4 -> 6 -> 0 ...
- and cl, 7 ; /
- sub byte [CS:SelfModB1-1], 2 ; 8 -> 6 -> 4 -> 2 -> 8 ...
- SelfW3:
- jnz NextChar ; process next char if not wrapped
- mov byte [CS:SelfModB1-1], 8 ; ^ wrap back to 8
- SelfW4:
- dec bp ; when register wrap adjust offset 2,2,2,1
- jmp NextChar ; process next char
- DoneDraw:
- mov ax, 0000h ; Self-modified (old SS)
- SelfModW1:
- mov ss,ax ; Restore SS
- sti ; Can enable interrupts now
- pop es
- pop ds
- popa
- retf
- ;%assign Fixup1 ((SelfW1-2)-$$)
- ;%assign Fixup2 ((SelfW2-2)-$$)
- ;%assign Fixup3 ((SelfW3-3)-$$)
- ;%assign Fixup4 ((SelfW4-3)-$$)
- ;%warning word in offset Fixup1 need fixup on QB
- ;%warning word in offset Fixup2 need fixup on QB
- ;%warning word in offset Fixup3 need fixup on QB
- ;%warning word in offset Fixup4 need fixup on QB
- %assign SegSet1 ((ModW1-2)-$$)
- %assign SegPtr1 ((ModW2-2)-$$)
- %warning word in offset SegSet1 must be set to FONT varseg on QB
- %warning word in offset SegPtr1 must be set to FONT varptr on QB
- section .data
- msg db "Hello World! ",1,32,3,4,5,6,13,14
- font incbin "DUNGEOLB.FNT",7
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement