Dgroup Group AsmData AsmData Dseg Common Word DataSP Rw 0 Rw 375 MyStack Rw 1 StOff Rw 1 StSeg Rw 1 Hi_Result Rw 1 Low_Result Rw 1 string db 'zyxg' port_num db 0 line_status dw 0 rx_buffer dw 0 tx_buffer dw 0 ; CSeg Extrn DD747x:Near Public LFetch LFetch: Push Bp Mov Bp, Sp Push Es Push Bx Push Si Mov Es, +4[Bp] Mov Bx, +6[Bp] Mov Si, +8[Bp] Shl Si,1 Mov Ax, Es:WORD PTR [Bx+Si] Pop Si Pop Bx Pop Es Pop Bp Ret Public LStore LStore: Push Bp Mov Bp, Sp Push Es Push Ax Push Di Push Bx Mov Es, +4[Bp] Mov Bx, +6[Bp] Mov Di, +8[Bp] Shl Di,1 Mov Ax, +10[Bp] Mov Es:WORD PTR [Bx+Di], Ax Pop Bx Pop Di Pop Ax Pop Es Pop Bp Ret Driver: Push Ds Pop Bx Push Ds Mov Ax, Seg DataSp Push Ax Pop Ds Mov Ax, Ss Mov StSeg, Ax Mov Ax, Sp Mov StOff, Ax Mov Sp, Offset MyStack Mov Ax, Ds Mov Ss, Ax Push Bp Push Dx Push Bx Call Dd747x Pop Es ; Trash top parameter Pop Dx Pop Bp Mov Ax, StSeg Mov Ss, Ax Mov Ax, StOff Mov Sp, Ax Pop Ds Retf Gdos_Int Equ 224 Gdos_Funct Equ 115 ; CP/M-86 I/O Routines ; Small model C Callable Param Equ Ss:(Word Ptr .8)[Bp] ; Parameter address in stack ; Sp+6 Offset Param ; +2 Offset Retaddr ; [Bp]: Sp OldBp Public TtyIn TtyIn: Mov Bx,00203h ; Channel 3 Get char, wait Push Di Push Si All_In: Callf Char_IO ; Call Bdos via Gdos via first-time sw Valid_Char: And Dx,07fh ; Mask off high order bit Stuff_Char: Push Bp ; Save caller's stack frame Mov Bp,Sp ; Make my own frame Push Ss Pop Es Mov Di,param ; Get pointer to parameter Mov Es:(Word Ptr .0)[Di],Dx ; Stuff character Pop Bp ; & Bp Pop Si Pop Di Ret Public TtyINW TtyINW: Mov Bx,00303h ; Channel 3, Get char, no wait Push Di Push Si Callf Char_IO ; Call Bdos via Gdos via first-time sw Js Valid_Char ; Jump if valid char in Dl Mov Dl,-1 ; Return -1 if not ready Jmps Stuff_Char ; Go to common stuffer Public RdrIn RdrIn: ; Mov Bx,00204h ; Channel 4 Get char, wait Push Di Push Si ; Jmps All_In ; Go to common get & stuff ; push ax mov line_status,3fdh ;com1: mov rx_buffer,3f8h cmp port_num,0 je port_found mov line_status,2fdh ;com2: mov rx_buffer,2f8h port_found: mov dx,line_status in_loop: in al,dx test al,1h jz in_loop ;wait for char in input buffer mov dx,rx_buffer in al,dx ;get character mov dl,al ;save it in dl mov dh,0h pop ax jmps valid_char ; Eject Public TtyOut TtyOut: Mov Bx,00603h ; Channel 3, wait, output Push Di Push Si AllOut: Push Bp ; Save caller's Bp Mov Bp,Sp ; Point into stack Mov Dl,(Byte Ptr .8)[Bp] ; Get the character to show Mov Dh,0 ; High order zero Callf Char_IO ; Call Bdos via Gdos via first-time sw Pop Bp ; & Bp Pop Si Pop Di Ret Public PchOut PchOut: ; Mov Bx,00604h ; Channel 4, wait, output ; push di ; push si ; Jmps AllOut ; Go do common Int ; push ax push dx push bp ;have to do three pushes mov bp,sp ;get param address in bp mov line_status,3fdh ;com1: mov tx_buffer,3f8h cmp port_num,0 je out_found mov line_status,2fdh ;com2: mov tx_buffer,2f8h out_found: mov dx,line_status out_loop: in al,dx test al,20h jz out_loop ;wait trans buffer to empty mov dx,tx_buffer mov al,(byte ptr .8)[bp] ;get char to output out dx,al ;send character pop bp pop dx pop ax ret ; Public LptOut LptOut: Mov Bx,00605h ; Channel 5, wait, output Push Di Push Si Jmps AllOut ; Go do common Int Public TtyInE TtyInE: Push Bp ; Save caller's Bp Mov Bp,Sp ; Point into stack Push Di Push Si Mov Dx,Param ; Point Ds:Dx to buffer Mov Bx,00803h ; Read Console Buffer opcode Callf Char_IO ; Call Bdos via Gdos via first-time sw Pop Si Pop Di Pop Bp ; & Bp Ret Eject Char_IO: Test CIO_Segment,0ffffh ; Already found where it is? Jz Find_It ; Jump if need to find layer 1 Char_jmpf: ; Jmpf Far Ptr 0:0 ; Hard jump becomes Jmpf layer1 db 0eah ; Jmpf CIO_Offset DW 0 ; Offset CIO_Segment Dw 0 ; & Seg Find_it: Push Ax ; Save registers Push Bx Push Cx Push Es Mov Cx,01600h+Gdos_Funct ; GDdos "Return Layer Pointer" function Int Gdos_Int ; Get ptr to layer 1 table entry Les Bx,Es:(DWord Ptr 1)[Bx] ; Es:Bx <- Ptr to layer 1 Mov CIO_Offset,Bx ; Fix up jump Mov CIO_Segment,Es Pop Es ; Restore registers Pop Cx Pop Bx Pop Ax Jmps Char_Jmpf ; & call Char I/O layer 1 Public MULDIV MULDIV: ;*********************************************************************; ; ; ; Function: Do 32 bit multiply and divide ; ; ; ; Input Parameters: ; ; multiply1 - first arg for multiply ; ; multiply2 - second arg for multiply ; ; divarg - divide argument ; ; ; ; Output Parameters: ; ; none ; ; Functional Output: ; ; result of (multiply1 * multiply2)/divarg ; ; ; ; Routines Called: ; ; none ; ;*********************************************************************; Push Bp Mov Bp,Sp ; ; result = muldiv(m1,m2,d) ; Xor Dx, Dx Mov Ax, (Word Ptr .4) [Bp] IMul (Word Ptr .6) [Bp] IDiv (Word Ptr .8) [Bp] Pop Bp Ret Public INTERCPT INTERCPT: ;*********************************************************************; ; ; ; Function: Do 32 bit multiply and divide for specific formula: ; ; INTERCPT=((raster-y2)*x1-(raster-y1)*x2)/(y1-y2+sign*(x1-x2)) ; ; ; ; Input Parameters: ; ; raster ; ; sign ; ; x1 ; ; y1 ; ; x2 ; ; y2 ; ; ; ; Output Parameters: ; ; none ; ; Functional Output: ; ; result of formula ; ; ; ; Routines Called: ; ; none ; ;*********************************************************************; Push Bp Mov Bp, Sp ; ; Result = ((raster-y2)*x1)/(y1-y2+sign*(x1-x2)) - (raster-y1)*x2)/(y1-y2+sign*(x1-x2)) ; Xor Dx, Dx Mov Ax, (Word Ptr .8) [Bp] ; Load x1 Sub Ax, (Word Ptr .12) [Bp] ; - x2 IMul (Word Ptr .6) [Bp] ; * sign Add Ax, (Word Ptr .10) [Bp] ; + y1 Sub Ax, (Word Ptr .14) [Bp] ; - y2 Mov Bx, Ax Xor Dx, Dx Mov Ax, (Word Ptr .4) [Bp] ; Load raster Sub Ax, (Word Ptr .14) [Bp] ; - y2 IMul (Word Ptr .8) [Bp] ; * x1 Mov Low_Result, Ax Mov Hi_Result, Dx Xor Dx, Dx Mov Ax, (Word Ptr .4) [Bp] ; Load raster Sub Ax, (Word Ptr .10) [Bp] ; - y1 IMul (Word Ptr .12) [Bp] ; * x2 Sub Word Ptr Low_Result, Ax ; - (raster-y1)*x2 Sbb Hi_Result, Dx Mov Ax, Low_Result Mov Dx, Hi_Result IDiv Bx Pop Bp Ret End Driver