diff options
Diffstat (limited to 'private/mvdm/vdd/samples/sample2/16bits/16bits.asm')
-rw-r--r-- | private/mvdm/vdd/samples/sample2/16bits/16bits.asm | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/private/mvdm/vdd/samples/sample2/16bits/16bits.asm b/private/mvdm/vdd/samples/sample2/16bits/16bits.asm new file mode 100644 index 000000000..093e69e91 --- /dev/null +++ b/private/mvdm/vdd/samples/sample2/16bits/16bits.asm @@ -0,0 +1,217 @@ + TITLE Sample 16 Bits DOS application +;---------------------------------------------------------------; +; + include 16bits.inc + + DOSSEG + .MODEL SMALL + + .STACK 100h + + .DATA + + +DMAWriteBuffer label byte + db 64 dup (?) +DMA_BUFFER_SIZE equ $ - DMAWriteBuffer + +DMAReadBuffer label byte + db DMA_BUFFER_SIZE dup (?) + +MIOPattern label byte + db 00, 0FFh, 0AAh, 055h +MIOPATTERN_SIZE equ $ - MIOPattern + +public start + + .CODE +start: + jmp short RealStart +OldVector label dword + dd ? +DMACompleted db ? + +RealStart: + mov ax,@DATA + mov ds,ax + mov es,ax + assume ds:@DATA, es:@DATA + +;Hook interrupt(DMA terminate count notification) + push ds + mov al, DMA_INTERRUPT + mov ah, 35h + int 21h + mov word ptr cs:OldVector, bx + mov word ptr cs:OldVector + 2, es + mov dx, offset ISRDMACompleted + mov ax, cs + mov ds, ax + mov al, DMA_INTERRUPT + mov ah, 25h + int 21h + pop ds + + +;VDD operation. +;(1). Hook the I/O port. +;(2). Keep the port status up-to-date if a write operation is performed +; by 16 bits application(this program). +;(3). Simulate DMA operation and generate a fake interrupt for 16bits +; applicatiion if the DMA operation reaches its TC. +; +; +;16bits application +;(1). Output one byte to the port and then request DMA operation. +;(2). Wait for DMA operation completed. +;(3). goto step (1) if there are more data to be transferred. +;Note that the given I/O must be a R/W port. + +;Here we do a DMA write operation upon I/O mapped I/O + mov cx, DMA_BUFFER_SIZE + mov si, offset DMAWriteBuffer +DMATransferLoop_Fast: + mov dx, IO_PORT_DMA + mov al, cl + out dx, al ;write I/O the current count + cli + mov cs:DMACompleted, FALSE ;reset TC flag + sti +;channel #1, write op, no auto init, addr inc, single transfer + mov al, 01000101B + call SetupDMAOperation +;Fire the DMA WRITE operation, this will cause VDD to gain control +;and start DMA operation. + mov dx, IO_PORT_FIRE_DMA_FAST + out dx, al +;In real world(there is a real hardware adapter), we won't do this +;idle loop, rather, we can do something useful(like, read the DMA current +;count and display the progress and so forth)provided that we can regain +;control while DMA operation is in progress(VDD spawns a new thread to +;handle DMA operation and returns to us immediately) +; +;Since we are simulating DMA operation without hardware, we always +;start the DMA operation with transfer count set to 1 byte. In reality +;this is should not be the case because it will slow down the data transfer. + +WaitForDMA_Fast: + cmp cs:DMACompleted, TRUE + jnz WaitForDMA_Fast + inc si + loop DMATransferLoop_Fast +; +;Now do a DMA read operation + mov cx, DMA_BUFFER_SIZE + mov si, offset DMAWriteBuffer + mov di, offset DMAReadBuffer +DMATransferLoop_Slow: +;channel #1, read op, no auto init, addr inc, single transfer + mov al, 01001001B + cli + mov cs:DMACompleted, FALSE + sti + call SetupDMAOperation +;Fire the DMA READ operation + mov dx, IO_PORT_FIRE_DMA_SLOW + out dx, al +WaitForDMA_Slow: + cmp cs:DMACompleted, TRUE + jne WaitForDMA_Slow + mov dx, IO_PORT_DMA + in al, dx + mov [di], al + inc di ;advance our buffer + inc si ;and the DMA buffer + loop DMATransferLoop_Slow +; +;The DMAWriteBuffer and DMAReadBuffer should have the same contents. +;If they don't, it failed. .... + + +;Memory mapped I/O + mov ax, MIO_SEGMENT + mov es, ax + mov bx, MIOPATTERN_SIZE + mov si, offset MIOPattern + +MIO_Loop: + cld + lodsb ;get next pattern + mov cx, MIO_PORT_RANGE + mov di, MIO_PORT_FIRST +rep stosb ;fill all I/O with the pattern + mov cx, MIO_PORT_RANGE + dec di + std +repe scasb ; + je @F +; call ErrorMIO ;if any i/o failed, +@@: + dec bx ;next pattern + jnz MIO_Loop + +;Before terminate, retsore everything we have touched + push ds + lds dx, cs:OldVector + mov al, DMA_INTERRUPT + mov ah, 25h + int 21h + pop ds + mov ah, 04Ch + int 21h + +;-------------------------------------------------------; +;Setup DMA operation +;Input: ds:si = seg:offset of memeory address +; al = DMA mode +;output: NONE +;Modified: AX, DX +;-------------------------------------------------------; +SetupDMAOperation proc + push cx + mov dx, DMA_PORT_FLIPFLOP + out dx, al + mov dx, DMA_PORT_MODE ;more register + out dx, al + mov ax, ds ;transfer address -> page:offset + mov cl, 4 ;page: A16 ~ A19, offset A0 ~ A15 + rol ax, cl + mov ch, al + and al, 0F0h + add ax, si + jnc @F + inc ch +@@: + mov dx, DMA_PORT_ADDR + out dx, al ;offset lower byte + mov al, ah + out dx, al ;and higher byte + mov dx, DMA_PORT_PAGE ;page register + mov al, ch + and al, 0Fh ;only 4 bits allowed + out dx, al + mov al, 1 ;single transfer, one byte + mov dx, DMA_PORT_COUNT + out dx, al + dec al + out dx, al ;higher byte set to 0 + mov dx, DMA_PORT_REQUEST ;request channel #1 + mov al, 00000101B + out dx, al + mov dx, DMA_PORT_SNGLE_MASK ;start DMA transfer + mov al, 00000001B + out dx, al + pop cx + ret +SetupDMAOperation endp + + +ISRDMACompleted proc far + mov byte ptr DMACompleted, TRUE + mov al, 20h + out 20h, al + out 0A0h, al + iret +ISRDMACompleted endp + +END start |