summaryrefslogtreecommitdiff
path: root/system/shard-x86-at/7/src/PCPLOT.ASM
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2019-02-11 11:49:19 +0100
committerLars-Dominik Braun <lars@6xq.net>2019-02-11 11:49:39 +0100
commit98cab31fc3659e33aef260efca55bf9f1753164c (patch)
treef1affa84049ef9b268e6c4f521f000478b0f3a8e /system/shard-x86-at/7/src/PCPLOT.ASM
parent71e2b36ccd05ea678e62e32ee6245df2b8d6ac17 (diff)
downloadeumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.tar.gz
eumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.tar.bz2
eumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.zip
Add source files from Michael
Diffstat (limited to 'system/shard-x86-at/7/src/PCPLOT.ASM')
-rw-r--r--system/shard-x86-at/7/src/PCPLOT.ASM430
1 files changed, 430 insertions, 0 deletions
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 <mov word ptr [first_shift],0ebd1h> ;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 <mov word ptr [jmp_or_not],07ebh> ;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