From 98cab31fc3659e33aef260efca55bf9f1753164c Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 11 Feb 2019 11:49:19 +0100 Subject: Add source files from Michael --- system/shard-x86-at/7/src/PCPLOT.ASM | 430 +++++++++++++++++++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100644 system/shard-x86-at/7/src/PCPLOT.ASM (limited to 'system/shard-x86-at/7/src/PCPLOT.ASM') diff --git a/system/shard-x86-at/7/src/PCPLOT.ASM b/system/shard-x86-at/7/src/PCPLOT.ASM new file mode 100644 index 0000000..6718e12 --- /dev/null +++ b/system/shard-x86-at/7/src/PCPLOT.ASM @@ -0,0 +1,430 @@ +;**************************************************************************** +;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================* +;* * +;* Graphikroutinen fuer IBM - PC * +;* * +;* * +;**************************************************************************** + +gr_base dw 03d0h ;default grahpic adress + +gr_pointer equ 4 ;pointer register of 6845 +gr_data equ 5 ;data register of 6845 +gr_msr equ 8 ;mode select register +gr_csr equ 9 ;color select register +gr_status equ 10 ;status register +gr_xmsr equ 10 ;extended mode select register +gr_cfgswitch equ 15 ;hercules config switch + +switch_mode: + cmp dh,1 + jz gm_switch ;tecmar graphics master + cmp dh,2 ;hercules + jz herc_switch + push dx + push ax + mov dx,[gr_base] + add dx,gr_xmsr ;tecmar auf normal mode setzen + mov al,0 + out (dx),al + jmp short $+2 ;io pause machen + add dx,gr_cfgswitch-gr_xmsr ;hercules configswitch + out (dx),al + pop ax + pop dx + mov byte ptr [plot_mode],0 ;kein mode, den wir direkt auswerten + mov al,dl + mov ah,0 + int 10h ;auf gewuenschten mode schalten + mov cx,0 + jnc mode_ok +unallowed_mode: + mov cx,-1 +mode_ok: + ret + +herc_switch: + mov word ptr [gr_base],03b0h + cmp dl,1 ;mode 0 ist erlaubt + jnc unallowed_mode + add dl,6 ;da steht der erste herculesmode + jmp short all_allowed +gm_switch: ;tecmar graphics master + cmp dl,6 ;werte 0 bis 5 erlaubt + jnc unallowed_mode + push dx + mov dx,[gr_base] + add dx,gr_status ;statusregister holen + in al,dx + pop dx + test al,80h ;schalter auf monochrom + jnz all_allowed ;nein, alle modi erlaubt + cmp dh,2 ;nur 0 und 1 + jnc unallowed_mode +all_allowed: + mov byte ptr [plot_mode],1 ;merken, dass in erweitertem mode + mov dh,0 + mov ax,offset mod_tb_length ;laenge einer tabelle + mul dx ;auf passende tabelle zeigen + mov bx,ax + add bx,offset mod_tables ;auf erstes byte der tabelle +; + mov ah,13 ;vierzehn register muessen ausgegeben werden + mov dx,[gr_base] + add dx,gr_msr ;da ist mode select register unserer graphik + mov al,0 ;disable screen output + out (dx),al + jmp short $+2 + add dx,gr_cfgswitch-gr_msr ;hercules einschalten (wenn da) + mov al,3 + out (dx),al + sub dx,gr_cfgswitch-gr_pointer + +set_6845: + mov al,ah + out (dx),al ;in dieses register wollen wir schreiben + inc dx ;und hier muss der wert hin + mov al,byte ptr [bx] + inc bx ;auf naechstes feld + out (dx),al + dec dx ;wieder auf zeiger_register + dec ah + jns set_6845 ;bis nummer negativ +; + cld + mov cx,08000h ;fill 64k + mov ax,0a000h + mov es,ax + xor ax,ax ;fill with 0 + xor di,di ;start at 0 in area + rep stosw + mov cx,08000h + mov ax,0b000h ;next 64k + mov es,ax + xor ax,ax ;fill with 0 + xor di,di ;start at 0 in area + rep stosw +; + mov al,byte ptr[bx] ;csr wert holen + inc bx + add dx,gr_csr-gr_pointer + out (dx),al +; + inc dx ;to xmsr + mov al,byte ptr [bx] + inc bx + out (dx),al +; + sub dx,gr_xmsr-gr_msr ;to msr + mov al,byte ptr [bx] + inc bx + out (dx),al +; + mov ax,word ptr [bx] ;laenge einer graphik zeile + inc bx + inc bx + mov word ptr [gr_linelength],ax +; + mov al,byte ptr [bx] ;maske, um ein pixel zu behalten + push ds + pop es + mov cx,16 + mov di,offset color_tab + rep stosb ;farbtabelle auf 3 initalisieren + mov ah,0 + inc bx + mov word ptr [gr_pixel_mask],ax + xor al,0ffh ;maske erzeugen, die ein pixel loescht + mov byte ptr [gr_pixel_inv_mask],al +; + mov word ptr [first_shift],9090h ;ersten shift wegnoppen + test byte ptr [bx],1 ;vier segmente ? + ifnz ;shift wieder eintragen + inc bx +; + mov al,byte ptr [bx] ;mask fuer pixel_pro_byte holen + inc bx + mov byte ptr [gr_pixel_per_byte_mask],al + mov word ptr [shift_count_shift],0c902h ;volles shift annehmen + mov word ptr [shift_count_shift+2],0c902h ;add cl,cl + mov ah,1 ;anzahl shifts, um byteoffset zu kriegen + shr al,1 ;bei mehr als zwei pixel ein shift weniger + jz shifts_nopped + inc ah + mov word ptr [shift_count_shift],09090h ;nops + shr al,1 ;bei acht pixel gar kein shift + jz shifts_nopped + inc ah + mov word ptr [shift_count_shift+2],09090h ;nops +shifts_nopped: + mov byte ptr [gr_byte_calc_shift],ah +; + mov si,bx + mov di,offset gr_segtable + mov cx,4 + rep movsw ;segmentwerte uebertragen + add bx,8 + mov cx,0 + ret + +pen: + mov word ptr [maske],dx + mov byte ptr [linetype],bl + ret + +new_pen1: + mov cx,bx ;bx merken + mov bx,offset color_tab + call set4 + mov cx,dx + call set4 + ret + +new_pen2: + mov cx,bx ;bx merken + mov bx,offset color_tab+8 ;zweite haelfte der tabelle + call set4 + mov cx,dx + call set4 + ret + +set4: + call set2 + mov cl,ch +set2: + mov al,cl + and al,15 ;nur untersten 4 bits behalten + mov byte ptr [bx],al + inc bx + mov al,cl + mov cl,4 + shr al,cl ;obersten 4 bits + mov byte ptr [bx],al + inc bx + ret + +mask_mode: + mov word ptr [jmp_or_not],9090h ;set mask mode + mov cx,word ptr [mask_count] ;alten mask_count zurueckliefern + mov word ptr [mask_count],bx + cmp dx,0 ;wirklich mask_mode gewuenscht + ifz ;nein, sprung wieder einbauen + ret + +move: + mov word ptr [altx],dx ;neuen x wert + mov word ptr [alty],bx ;und y wert setzen + ret + +draw: + mov byte ptr [stepx],46h ;inc si + mov byte ptr [stepy],47h ;inc di + mov cx,dx ;in welche richtung wie weit gehen + sub cx,word ptr [altx] + jns positiv_x + neg cx ;negative richtung, positiv machen und + mov byte ptr [stepx],4eh ;dec si zum ausgleich +positiv_x: + mov dx,bx ;y wert holen + sub dx,word ptr [alty] ;wie weit und welche richtung + jns positiv_y + neg dx ;negative richtung, positiv rechnen und + mov byte ptr [stepy],4fh ;dec di zur korrektur +positiv_y: + cmp dx,cx ;hauptrichtung entlang des groesseren + ;offsets + jc direction_ok ;hauptrichtung war entlang si + mov bx,word ptr [stepy] ;richtungen tauschen + xchg bh,bl + mov word ptr [stepy],bx + xchg cx,dx ;und richtungslaengen tauschen + ;hauptrichtung ist jetzt entlang di +direction_ok: + ;der wert fuer die hauptrichtung ist + ;in cx, fuer die nebenrichtung in dx + ;der fehlerwert der nebenrichtung in + ;1/abs(hauptrichtung) - einheiten ist in bx + mov bx,0 ;fehlerwert ist im moment 0 + mov word ptr [delta_x],cx ;wert fuer hauptrichtung merken + mov si,word ptr [altx] ;alte werte holen + mov di,word ptr [alty] +paint: + jcxz paint_done ;fertig, letzten punkt noch malen + sub bx,dx ;ist gerader fehler schon negativ + jns stepx ;nur hauptrichtung nehmen + mov ax,bx ;geraden fehler nach ax + add ax,ax ; + add ax,word ptr [delta_x] ; + jns stepx ;nur hauptrichtung + add bx,word ptr [delta_x] +stepy: + inc di +stepx: + inc si + +; errechneten punkt setzen + + call punkt + + loop paint + +paint_done: + call punkt ;letzten punkt setzen + mov word ptr [alty],di + mov word ptr [altx],si + ret + + +punkt: + test byte ptr [plot_mode],0ffh + jnz new_punkt + push cx + push dx + mov dx,di + mov cx,si + ror word ptr maske,1 +linetype equ $+1 + mov ax,0c01h ;write dot + and al,byte ptr [maske] ;linie einbauen + int 10h + pop dx + pop cx + ret + +new_punkt: + push ax + push bx + push cx + push dx + push es + mov bx,di + and bx,3 + add bx,bx ; *2 + mov es,[bx+gr_segtable] ;in diesem segment liegt unser punkt +gr_linelength equ $+1 + mov ax,720/4 ;bytes pro zeile horizontal + mov bx,di ;y wert wieder holen +first_shift: ;dieser shift faellt bei zwei segmenten aus + shr bx,1 + shr bx,1 ;di / 4 + mul bx ;mal anzahl bytes pro graphikzeile + mov bx,si ;byte in zeile ausrechnen +gr_byte_calc_shift equ $+1 + mov cl,2 ;so oft si shiften, fuer byte in zeile + shr bx,cl + add bx,ax ;dies byte enthaelt unseren punkt + mov cx,si ;untersten bits geben shiftfaktor an + inc cx ;einmal mehr shiften (oder gar nicht) +gr_pixel_per_byte_mask equ $+2 + and cl,3 ;vier pixel pro byte (15 fuer zwei pixel etc +shift_count_shift: + add cl,cl ;shiftfaktor verdoppeln + add cl,cl ;oder vervierfachen + mov al,byte ptr es:[bx] ;byte holen + rol al,cl ;pixel nach 0 holen + mov bp,ax ;evtl. wird pixelwert als index benutzt +gr_pixel_mask equ $+2 + and bp,3 ;die pixel bits behalten +jmp_or_not: + jmp short punkt_no_mask +mask_count equ $+1 ;zaehler fuer maske + mov bp,0 + and bp,15 ;maskenzaehler MOD 16 nehmen +punkt_no_mask: +gr_pixel_inv_mask equ $+1 + and al,0fch ;rest behalten + or al,byte ptr ds:[bp+color_tab] ;pixel setzen + ror al,cl ;zurueckdrehen + mov byte ptr es:[bx],al ;wieder eintragen + inc word ptr ds:[mask_count] + pop es + pop dx + pop cx + pop bx + pop ax + ret + + even + +maske dw 0ffffh +altx dw 0 +alty dw 0 +delta_x dw 0 +;gr_pixel_mask dw 3 ;maske, welche bits zum pixel gehoeren +;mask_count dw 0 ;zaehler fuer maskiertes schreiben + +gr_segtable dw 0a000h ;tabelle der graphik segmente + dw 0a800h + dw 0b000h + dw 0b800h + + +;gr_linelength dw 720/4 ;laenge einer graphikzeile +;mask_mod db 0 ;nicht 0, wenn mit maske +color_tab db 16 DUP (3) ;farbtabelle + +plot_mode db 0 + +;gr_pixel_inv_mask db 0fch ;invertiert, nur byte + + + +mod_tables equ $ +;mode 0 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,2,88,86,1,91,14,90,90,109, 0, 191, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +mod_tb_length equ $-mod_tables +;mode 1 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,3,88,86,1,91,14,90,90,109, 0, 191, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +;mode 2 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,1,2,112,100,6,127,15,184,160,227, 0, 31, 24 + dw 640/2 ;laenge einer graphikzeile + db 15 ;maske, um ein pixel zu behalten + db 0 ;1 = 4 segmente, 0 = 2 segmente + db 1 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0a000h,0a800h ;die vier segmente +;mode 3 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,3,56,50,1,64,15,184,160,227, 0, 31, 24 + dw 640/2 ;laenge einer graphikzeile + db 15 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 1 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +;mode 4 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,1,2,112,100,7,127,15,98,90,128, 0, 63, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 0 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0a000h,0a800h ;die vier segmente +;mode 5 +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,32,3,3,56,50,3,64,15,98,90,128, 0, 63, 11 + dw 720/4 ;laenge einer graphikzeile + db 3 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 3 ;maske, um si MOD pixel_pro_byte zu machen + dw 0a000h,0a800h,0b000h,0b800h ;die vier segmente +;mode 6 (hercules) +; 6845 regs 13 - 0,csr,xmsr,msr + db 0,0,0,0,3,2,87,87,2,91,7,46,45,53, 0, 0, 10 + dw 720/8 ;laenge einer graphikzeile + db 1 ;maske, um ein pixel zu behalten + db 1 ;1 = 4 segmente, 0 = 2 segmente + db 7 ;maske, um si MOD pixel_pro_byte zu machen + dw 0b000h,0b200h,0b400h,0b600h ;die vier segmente +  \ No newline at end of file -- cgit v1.2.3