Embed
Email

code

Document Sample
code
Shared by: HC111202191421
Categories
Tags
Stats
views:
0
posted:
12/2/2011
language:
English
pages:
78
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;

; The driver file for the Oscilloscope (driver.asm)

;

; Initializes everything, and goes to

; Main loop

;::::::::::::::::::::::::::::::::::::::::::

;Revision History

;-4/21/02 Initial Revision, with keypad operational

;-5/13/02 Analog Section added

;-5/18/02 Analog Section functional

;-5/22/02 Added VRAM sections of initialization

;-6/13/02 Added Initialization code, double buffering

;Author: Yiyang Gong







NAME tester



CGROUP GROUP CODE

DGROUP GROUP DATA, STACK



EXTRN InitCS:NEAR ;initialize MMCS, PCS values

;From initial.asm

EXTRN InitKeypadTimer:NEAR ;initialize the timer for keypad (timer2)

;From keypad.asm

EXTRN InstallKeypadHandler:Near ;initialize the keypad interrupt handler (from

;timer2)

;From keypad.asm

EXTRN ClrIRQVectors:NEAR ;clear the Interrupt vectors, for boot

;From initial.asm

EXTRN InitializeKeypadCounts:NEAR ;initialize the counts for the keypad

;From keypad.asm

EXTRN InstallTriggerHandlers:NEAR ;initializes the trigger interrupt handlers

;(from int0, timer0)

;From trigger.asm

EXTRN InitTriggerTimer:NEAR ;initialize the trigger delay timer

;and the sampling timer (timer0, timer1)

;From trigger.asm

EXTRN InitTriggerValues:NEAR ;initialize the first trigger value

;and all the counts of the trigger handlers

;From trigger.asm

EXTRN Main:Near ;the mainloop from C functions

;From main.c

EXTRN LScope:NEAR ;Easter Egg - the boot screen

;From lcd.asm

EXTRN InitBuffer:NEAR ;Initiates the double buffer positions

;From lcd.asm



$include(maininit.inc)



CODE SEGMENT PUBLIC 'CODE'



ASSUME CS:CGROUP, DS:DGROUP, SS:DGROUP





;Pseudo Code

;Initialize the 80188 selects ;call InitCS

;Clear interrupt vectors ;call ClrIRQVectors

;Clear Digit

;Clear Segment

;Install Interrupt handler ;Call InstallHandler

;Initialize times ;Call InitTimer

;Enable interrupts

;CALL the main loop

;END





START LABEL FAR

CLI







27

MOV DX, LMCSReg ;set up the RAM chip select

MOV AX, LMCSVal

OUT DX, AL



MOV AX, STACK ;initialize the stack pointer

MOV SS, AX

MOV SP, OFFSET(DGROUP:TopOfStack)



MOV AX, DGROUP ;initialize the data segment

MOV DS, AX



MOV AX, DGROUP ;initialize the ES pointer

MOV ES, AX







CALL InitCS ;initialize the 80188 chip selects

; assumes LCS and UCS already setup



CALL ClrIRQVectors ;clear (initialize) interrupt vector table



CALL InstallKeypadHandler ;install the event handler

; ALWAYS install handlers before

; allowing the hardware to interrupt.



CALL InitKeypadTimer ;initialize the keypad timer (timer 2)



CALL InitializeKeypadCounts ;Initialize the keypad counts



CALL InstallTriggerHandlers ;initialize the trigger interrupt handlers

;from int0 and timer0

CALL InitTriggerTimer ;initialize the trigger delay counter (timer0)

;and the trigger sampling counter (timer1)

CALL InitTriggerValues ;initialize all the trigger counters, as well

;as give an initial trigger value/slope



CALL InitBuffer ;initialize the buffer positions



STI ;and finally allow interrupts.



LOOPER:

CALL LScope ;Easter Egg - boot screen

;exited from with a keypress

CALL Main ;the main loop that never returns



Looper1:

;should never reach here

JMP Looper1





CODE ENDS







ASSUME CS:POWER_ON ;the initial code to run

;when the power is turned on



POWER_ON SEGMENT



MOV DX, UMCS_REG ;setup the UMCS register

MOV AX, UMCS_VAL ;for access to the ROM

OUT DX, AL

JMP START ;JMP to the start of the code



POWER_ON ENDS



;the data segment



DATA SEGMENT PUBLIC 'DATA'









28

DATA ENDS









;the stack



STACK SEGMENT STACK 'STACK'



DB 80 DUP ('Stack ') ;240 words



TopOfStack LABEL WORD



STACK ENDS







END









29

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;

; Initialization constants (maininit.inc)

; sets up ROM and RAM in memory

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Revision History

;-6/13/02 Added constants for UMCS, LMCS initialization

;

;



UMCS_REG EQU 0FFA0H ;the address of the UCS controller

UMCS_VAL EQU 03000H ;sets up UCS from F0000H to FFFFFH, no wait states



LMCSReg EQU 0FFA2H ;the address of the UCS controller

LMCSVal EQU 007C0H ;set up LCS from 00000H to 0FFFFH, no wait states









30

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;

; The initialization CS (init.asm)

;

;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Table of Contents

;-InitCS() –

; This function will initializes the PCS select lines (for trigger delay

; control, trigger value writes, and double buffer selects)

; and the MCS select for the VRAM read and writes

;-ClrIRQVectors –

; Clear the interrupt vector by filling with the illegal event handler

;-IllegalEventHandler –

; A function that should never be reached. But if it is reached,

; it sends a Non-specific EOI to clear the most significant interrupt.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Revision History (difference from Glen George code)

;-4/20/02 Initial revision after EE51, added comments

;-5/27/02 Added MMCS values for VRAM

;Author: Yiyang Gong





NAME Initialization ;Yiyang Gong

CGROUP GROUP CODE



$INCLUDE(init.INC)



CODE SEGMENT PUBLIC 'CODE'



ASSUME CS:CGROUP





; InitCS

;

; Description: Initialize the Peripheral Chip Selects on the 80188.

;

; Arguments: None.

; Return Value: None.

;

; Local Variables: None.

; Shared Variables: None.

; Global Variables: None.

;

; Input: None.

; Output: None.

;

; Error Handling: None.

;

; Algorithms: None.

; Data Structures: None.

;

; Registers Used: AX, DX

;

;Author: Yiyang Gong

; Copied from Glen George InitCS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Pseudo Code

;Setup write to PACS

;Write to PACS register the number of wait states and base

;Setup write to MPCS register

;Write to MPCS register the number of wait states and I/O space

;END

;Revision History

;-10/29/97 Glen George Final revision

;-5/27/02 Added MMCS values for VRAM





InitCS PROC NEAR







31

public InitCS



PUSH DX ;save registers

PUSH AX



MOV DX, PACSreg ;setup to write to PACS register

MOV AX, PACSval

OUT DX, AL ;write PACSval to PACS (base at 0, 0 wait states)



MOV DX, MPCSreg ;setup to write to MPCS register

MOV AX, MPCSval

OUT DX, AL ;write MPCSval to MPCS (I/O space, 0 wait states)



MOV DX, MMCSreg ;setup to write to MMCS register

MOV AX, MMCSval

OUT DX, AL ;write MMCSval to MMCS (base at 4000H, 0 wait states)



POP AX ;restore registers

POP DX

RET ;done so return





InitCS ENDP





; ClrIRQVectors

;

; Description: This functions installs the IllegalEventHandler for all

; interrupt vectors in the interrupt vector table. Note

; that all 256 vectors are initialized so the code must be

; located above 400H. The initialization skips the first

; RESERVED_VECS vectors.

;

; Arguments: None.

; Return Value: None.

;

; Local Variables: CX - vector counter.

; ES:SI - pointer to vector table.

; Shared Variables: None.

; Global Variables: None.

;

; Input: None.

; Output: None.

;

; Error Handling: None.

;

; Algorithms: None.

; Data Structures: None.

;

; Registers Used: flags, AX, CX, SI, ES

;

;Pseudo Code

;

;Clear ES

;Initialize SI to skip reserved vectors (4 bytes)

;Initialize rest of interrupt vectors

;Set start address

;REPEAT

; Current vector (at start address) = address of illegal event handler

; Move start address to next vector

;UNTIL start address > interrupt vector + vector size

;

;END

;Revision History

;-1/28/02 Glen George Final Revision

;-4/20/02 Yiyang Gong Added comments



ClrIRQVectors PROC NEAR

PUBLIC CLRIRQVECTORS



PUSH AX ;save registers







32

PUSH CX

PUSH ES

PUSH SI



InitClrVectorLoop:



XOR AX, AX ;clear ES (interrupt vectors are in segment 0)

MOV ES, AX

MOV SI, 4 * RESERVED_VECS ;initialize SI to skip RESERVED_VECS (4 bytes

;each)



MOV CX, 256 - RESERVED_VECS ;up to 256 vectors to initialize





ClrVectorLoop: ;loop clearing each vector

;store the vector

MOV ES: WORD PTR [SI], OFFSET(IllegalEventHandler)

MOV ES: WORD PTR [SI + 2], SEG(IllegalEventHandler)



ADD SI, 4 ;update pointer to next vector



LOOP ClrVectorLoop ;loop until have cleared all vectors

;JMP EndClrIRQVectors;and all done





EndClrIRQVectors:

POP SI ;restore registers

POP ES

POP CX

POP AX

RET ;all done, return





ClrIRQVectors ENDP









; IllegalEventHandler

;

; Description: This procedure is the event handler for illegal

; (uninitialized) interrupts. It does nothing - it just

; returns after sending a non-specific EOI.

;

; Arguments: None.

; Return Value: None.

;

; Local Variables: None.

; Shared Variables: None.

; Global Variables: None.

;

; Input: None.

; Output: None.

;

; Error Handling: None.

;

; Algorithms: None.

; Data Structures: None.

;

; Registers Used: None

;

;Pseudo Code

;

;Send non-specific EOI

;END

;Revision History

;-12/25/00 Glen George Final Revision

;-4/20/02 Yiyang Gong added comments

;



IllegalEventHandler PROC NEAR







33

PUBLIC ILLEGALEVENTHANDLER



PUSH AX ;save the registers

PUSH DX



MOV DX, INTCtrlrEOI ;send a non-sepecific EOI to the

MOV AX, NonSpecEOI ; interrupt controller to clear out

OUT DX, AX ; the interrupt that got us here



POP DX ;restore the registers

POP AX



IRET ;and return





IllegalEventHandler ENDP



CODE ENDS



END









34

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

; Init.INC

; Include File for initialization of CPU

;

; CS and interrupts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;This file is for the initialization of keypad timers and keypad counts

; Revision History:

; 5/5/02 - Initial revision







; Interrupt Controller Definitions



; Addresses

INTCtrlrCtrl EQU 0FF32H ;address of interrupt controller for timer

INTCtrlrEOI EQU 0FF22H ;address of interrupt controller EOI



; Chip Select Unit Definitions

; Addresses

PACSreg EQU 0FFA4H ;address of PACS register

MPCSreg EQU 0FFA8H ;address of MPCS register

MMCSreg EQU 0FFA6H ;address of MMCS register



NonSpecEOI EQU 08000H ;Non-specific EOI command



; Control Register Values

PACSval EQU 00000H ;PCS base at 0, 0 wait states

MPCSval EQU 02080H ;PCS in I/O space, use PCS5/6, 0 wait states



MMCSval EQU 04000H ;01000000-------- MCS starting address is 40000H with 256K address

;-------------000 no wait states



;General Definitions



RESERVED_VECS EQU 0 ;vectors reserved for debugger









35

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

; KeyPad (keypad.asm)

; file for handling the keypad debouncing, autorepeating

; based on timer2 interrupts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;KeypadEventHandler() -

; The event handler from timer2. It will call the scandebounce

; function from the keypad file.

;InitKeypadTimer() -

; Initializes the keypad timer (timer 2) for counting milliseconds

; and thus scanning for a keypress every millisecond

;InstallKeypadHandler() -

; Install the keypad handler in the interrupt vector (at

; position for timer2)

;InitializeKeypadCounts() -

; The function initializes the counts for the keypad and the timer

; for keypad scanning

;GetKey() -

; The function calls keyavailable() to see if a key is debounced

; and then converts the debounced key to a keycode. The key code is then

; returned in AX.

;KeyAvailable() -

; The function checks if a key is available by checking the debounce flag.

; The function will then return the status in AL.

;ScanDebounce() -

; The function is called with every timer2 interrupt.

; The function first checks if a key is scanned in on the keypad. Then

; the key is either registered as a new, or debounced. If the key was already

; debounced, then the key is autorepeated at some rate.

;Author: Yiyang Gong

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Revision History

;-2/14/02 initial revision with timer event handler, added all commments

;-2/24/02 initial revision with scandebounce and functioning keypad

;-3/15/02 changed keycodes to 0-11

;-4/21/02 changed keycode to 0-5 for the oscilloscope, by changing the

; key table values, and deleting test cases for three ports

; (as the new "keypad"





NAME KeyPad



CGROUP GROUP CODE

DGROUP GROUP DATA



$INCLUDE(keypad.INC)

$INCLUDE(init.inc)



CODE SEGMENT PUBLIC 'CODE'



ASSUME CS:CGROUP, DS:DGROUP







;InitializeKeypadCounts()

;Description:

; Initializes all the counts and flags used by the keypad program

;Arguments: None

;Return Value: None

;Local Variables: None

;Shared Variables: CurrentKey - the current key scanned in by scandebounce()

; DebounceFlag - the flag status of a key being debounced

; AutoRepeatCount - Once the keypad starts autorepeating

; this count is used

; DebounceCount - When the keypad is debouncing a key,

; this count is used

; MaxCount - the count to count to, for either

; debouncing or autorepeating

; Keycode - the code to return for any key

;Global Variables: None







36

;Input: None

;Output: None

;Error Handling: None

;Algorithms: None

;Data Structures: None

;Registers Used: None

;Pseudo Code

; Start the key count at zero

; Set the debounce flag to false

; Set repeat count, autorepeatcount to zero

; Establish the max count

; Set the initial keycode

;END

;Revision History

;2/14/02 Yiyang Gong Initial Revision



InitializeKeypadCounts PROC NEAR

Public InitializeKeyPadCounts



MOV CurrentKey, EmptyKey ;no key has been scanned

MOV DebounceFlag, False ;no key has been debounced

MOV AutoRepeatCount, 0

MOV DebounceCount, 0 ;start counts at zero when begin counting

MOV MaxCount, MaxDebounceCount ;in debounce mode, use debounce maximum

MOV KeyCode, EmptyKey ;empties keycode

RET

InitializeKeypadCounts ENDP



;KeypadEventHandler

;Description: This function takes care of scanning for a keypress and

; debouncing the key. In the event handler, the scandebounce function

; is called. This abstraction allows for other functions to be on

; the same timer.

;Arguments: None

;Return Value: None

;Local Variables: None

;Shared Variables: None

;Global Variables: None

;Input: A key pressed

;Output: None

;Error Handling: None

;Algorithms: None

;Data Structures: None

;Registers Used: AX, DX



;Pseudo Code

;CALL scandebounce

;Send EOI

;END

;Revision History

;2/24/02 Yiyang Gong added ScanDebounce





KeypadEventHandler PROC NEAR

Public KeypadEventHandler



PUSH DX

PUSH AX



CALL ScanDebounce ;call to see if a key has been found

;or is being debounced



EndTimerEventHandler: ;done taking care of the timer



MOV DX, INTCtrlrEOI ;send the EOI to the interrupt controller

MOV AX, Timer0EOI

OUT DX, AL



POP AX ;restore the registers

POP DX

IRET







37

KeypadEventHandler ENDP





; InitKeypadTimer

;

; Description: Initialize the 80188 Timer2. The timer2 are initialized

; to generate a count every millisecond. The

; interrupt controller is initialized to allow the

; timer2 interrupts.

;

; Arguments: None.

; Return Value: None.

;

; Local Variables: None.

; Shared Variables: None.

; Global Variables: None.

;

; Input: None.

; Output: None.

;

; Error Handling: None.

;

; Algorithms: None.

; Data Structures: None.

;

; Registers Used: AX, DX

;

;Pseudo Code

;count register = 0

;initialize timer #2 for a constant interval between timer interrupt

;send to interrupt controller

;setup max count per second

;send to interrupt controller

;reset interrupts, sets control register

;send to interrupt controller

;send EOI

;END

;Revision History

;10/29/97 Glen George Final revision

;2/14/02 Yiyang Gong revision to work with keypad and 16Mhz clock

;4/20/02 Yiyang Gong revision, no need for interrupts





InitKeypadTimer PROC NEAR

Public InitKeypadTimer



PUSH DX

PUSH AX

;initialize Timer #2 as a prescalar

MOV DX, Tmr2Count ;initialize the count register to 0

XOR AX, AX

OUT DX, AL



MOV DX, Tmr2MaxCnt ;setup max count for 1ms counts

MOV AX, COUNTS_PER_MS

OUT DX, AL



MOV DX, Tmr2Ctrl ;setup the control register, no interrupts

MOV AX, Tmr2CtrlVal

OUT DX, AL



MOV DX, INTCtrlrCtrl ;setup the interrupt control register

MOV AX, INTCtrlrCVal

OUT DX, AL



MOV DX, INTCtrlrEOI ;send a non-specific EOI (to clear out controller)

MOV AX, NonSpecEOI

OUT DX, AL



POP AX







38

POP DX



RET ;done so return



InitKeypadTimer ENDP









; InstallKeypadHandler

;

; Description: Install the event handler for the timer interrupt.

;

; Arguments: None.

; Return Value: None.

;

; Local Variables: None.

; Shared Variables: None.

; Global Variables: None.

;

; Input: None.

; Output: None.

;

; Error Handling: None.

;

; Algorithms: None.

; Data Structures: None.

;

; Registers Used: AX, ES

;

;Pseudo Code

;

;Clear interrupt vector

;Store start vector address (of timerEventHandler)

;Initialize all values of the vector

;END

;Revision History

; 1/28/02 Glen George Final Revision

; 2/14/02 Yiyang Gong Added comments

;



InstallKeypadHandler PROC NEAR

PUBLIC InstallKeypadHandler



PUSH ES ;save registers

PUSH AX



XOR AX, AX ;clear ES (interrupt vectors are in segment 0)

MOV ES, AX

;store the vector

MOV ES: WORD PTR (4 * Tmr2Vec), OFFSET(KeypadEventHandler)

MOV ES: WORD PTR (4 * Tmr2Vec + 2), SEG(KeypadEventHandler)



POP AX ;restore registers

POP ES

RET ;all done, return





InstallKeypadHandler ENDP





;GetKey()

;Description: This function is called with no arguments and returns with the code

;for the key pressed on the keypad in register AL. The procedure should only return fully

;debounced key presses. The routine returns with the key code after the key has been

;pressed and debounced, but not necessarily released. The procedure does not return until

;a key has been pressed.

;

;Arguments: none

;Return value: Keycode in AL

;Local Variables: None







39

;Shared Variables: Keycode – the actual key(s) pressed

; DebounceCount – the count used during debouncing to find

; a key

; DebounceFlag – the flag for the status of the debounced key

;Global Variables: None

;Input: Key pressed, but not necessarily released

;Output: None

;Error Handling: None

;Registers used: flags, AX, BX, CX

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitation: Doesn’t know when key is released

;

;Pseudo Code

;

;Repeat

; Key_Available()

;Until zero flag = reset

;

; AL = keycode

; Table lookup AL to convert to keycode

; AL = value from table

; Reset to scan for a new key

;END

;Revision History

;2/14/02 Yiyang Gong initial revision

;2/24/02 Yiyang Gong fixed bug of setting flags

;4/12/02 Yiyang Gong changed table lookup method

; to return the keycode





GetKey PROC NEAR

Public GetKey



PUSH BX ;save registers

PUSH CX

PUSH DX



BLOCKERLOOP:

CALL Key_Available ;blocker function



BLOCKERCHECK:

CMP AL, False

JZ BLOCKERLOOP ;check zeroflag

;JNZ CONVERTKEY

;IF there is a key THEN

MOV BX, OFFSET(KeyTable) ;BX points at table

MOV CX, Offset(KeyTable) ;save the position of the table

DEC BX ;start table lookup loop



CONVERTKEY:

INC BX ;move to the next position of table

MOV AL, KeyCode ;move in the keycode

AND AL, EmptyKey ;only use low 5 bits of AL



MOV DL, CS:[BX] ;make sure that the key is valid

CMP DL, Key_Scan_Illegal ;IF Key is Valid THEN

JE ENDGETKEY

;JNE continue



CMP AL, CS:[BX] ;Check if the current position

JNE CONVERTKEY ;has the correct key

;JE ENDGETKEY ;If so THEN get the keycode

;ELSE loop back to converkey

ENDGETKEY:

SUB BX, CX ;get the position from the table lookup

MOV AL, BL ;put the position in the return value

XOR AH, AH ;clear AH, as return value is AX

MOV DebounceCount, Reset ;return debounce count to 0

MOV DebounceFlag, False ;stop getting the key







40

POP DX ;restore registers

POP CX

POP BX

RET

GetKey ENDP









;KeyAvailable()

;Description:

;The function is called with no arguments and returns with the AX reset

;if there is a key available and the zero flag set otherwise. In other words, if

;KeyAvailable() returns with the AX reset that means GetKey would return

;immediately if called because there is a key available (it won't need to wait

;for a key to be pressed). This function does not affect whether or not a key

;is available.

;Arguments: None

;Return value: AX set or reset

;Local Variables: None

;Shared Variables: None

;Global Variables: DebounceFlag - if a key has been debounced

; KeyCode - the data of the key pressed

;Input: Key pressed, but not necessarily released

;Output: None

;Error Handling: None

;Registers used: AX, flags

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitation: None

;

;Pseudo Code

;ScanDebounce()

;If DebounceFlag = set THEN

; set AX to false

;Else

; set AX to true

;ENDIF

;END

;Revision History

;2/24/02 Yiyang Gong Initial revision

;4/20/02 Yiyang Gong changed the function to return

; the flag in AX instead of the zero flag





Key_Available PROC NEAR

Public Key_Available



CMP DebounceFlag, False ;IF the Key is ready THEN

JE NoKeyAvailable

;JNE KeyIsAvailable



KeyIsAvailable: ;Set AX to be True

MOV AX, True

JMP KeyAvailableEnd



NoKeyAvailable:

MOV AX, False ;Set AX to be False

;JMP KeyAvailableEnd



KeyAvailableEnd: ;ENDIF

RET



Key_Available ENDP









41

;ScanDebounce()

;Description: If a key is available, then checks to debounce the key. It then auto

;repeats (checks with a longer interval) to make sure key is pressed. If a key is not

;available, scan the keypad for keys pressed.

;Arguments: None

;Return value: Zero flag set or reset

;Local Variables: NewKey – the key scanned in one loop

;Shared Variables: CurrentKey – the key to be compared to for debouncing

; DebounceCount – the count that increments with the key that is being

; debounced

; AutoRepeatCount – the count that increments with the key that is

; autorepeated

; DebounceFlag – if a key has been debounced

; KeyCode – the data of the key pressed

; MaxCount – Once DebounceCount reaches this constant, the key will be

; debounced.

;Global Variables: None

;Input: Key pressed, but not necessarily released

;Output: None

;Error Handling: None

;Registers used: flags, AX, BX, CX, DX

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitation: None

;

;Pseudo Code

;CurrentKey initialized to zero

;If CurrentKey = EmptyKey THEN

; Inc. I

; Scan keyport(I)

; Currentkey = scanned value

;ELSE

; IF DebounceFlag = set THEN

; Scan keyport(I)

; IF scanned value = Currentkey THEN

; Inc AutoRepeatCount

; ELSE

; DebounceFlag = reset

; Count = 0

; MaxCount = MaxDebounceCount

; ENDIF

; ELSE

; Scan Keyport(I)

; IF currentkey = scanned value THEN

; Inc DebounceCount

; Else

; DebounceCount = 0

; ENDIF

; ENDIF

;ENDIF

;

;IF DebounceCount = MaxCount THEN

; KeyCode = currentKey

; DebounceFlag = set

; MaxCount = MaxAutoCount

; DebounceCount = zero

;ENDIF

;

;IF AutoRepeatCount = MaxCount THEN

; KeyCode = currentKey

; DebounceFlag = set

; AutoRepeatCount = 0

;ENDIF

;END

;Revision History

;-2/14/02 final revision from EE51

;-4/20/02 deleted all tests for different ports

; as the port is all the base PCS select with only

; five keys







42

ScanDebounce PROC NEAR

Public ScanDebounce



PUSH AX ;save registers

PUSH BX

PUSH CX

PUSH DX



CMP CurrentKey, EmptyKey

JNE DEBOUNCESTATE

;JE SCANSTATE



SCANSTATE:



GETTHEKEY:

XOR DX, DX ;set up DX for keypad ports

MOV DL, PortNumber ;DX = keyport

IN AL, DX ;take in the value of the key

AND AL, EmptyKey

MOV CurrentKey, AL ;put value in current key

MOV AutoRepeatCount, Reset ;reset the counts for debouncing/autorepeating

MOV DebounceCount, Reset

MOV AX, MaxDebounceCount ;Maxcount = MaxDebounceCount (in debounce mode)

MOV MaxCount, AX ;through the AX register - no memory

;to memory access

JMP ENDSCANDEBOUNCE



DEBOUNCESTATE:

CMP DebounceFlag, True ;IF DebounceFlag = set THEN

JNE DEBOUNCING

;JE AUTOREPEATING



AUTOREPEATING:

XOR DX, DX ;prep DX for portnumber

MOV DL, PortNumber ;move in DX for keypad port

IN AL, DX ;take in value from port

AND AL, EmptyKey

MOV BL, CurrentKey ;prepare to compare CurrentKey and scanned key

CMP AL, BL

JNE RESETEVERYTHING ;IF CurrentKey = scannedkey

;JE CONTINUEREPEAT



CONTINUEREPEAT:

INC AutoRepeatCount ;AutoRepeatCount is incremented (as autorepeat

condition is met)

JMP ENDAUTOREPEAT



RESETEVERYTHING:

MOV DebounceFlag, False ;ELSE

MOV AutoRepeatCount, Reset ;reset all counts and debouncestate flags

MOV DebounceCount, Reset ;the new key requires new counts for

;debouncing and autorepeating

MOV AX, MaxDebounceCount ;in debounce mode, so used the

MOV MaxCount, AX ;max count that is for debouncing

MOV CurrentKey, EmptyKey ;make the current

;JMP ENDAUTOREPEAT



ENDAUTOREPEAT:

JMP ENDDEBOUNCESTATE ;ENDIF



DEBOUNCING:

XOR DX, DX ;prep DX for portnumber

MOV DL, PortNumber ;put in port number

IN AL, DX ;get value from keypad

AND AL, EmptyKey

MOV BL, CurrentKey ;prep BL to compare currentkey and scannedkey

CMP AL, BL

JNE RESETEVERYTHING1 ;IF currentkey = scannedkey

;JE CONTINUEDEBOUNCE









43

CONTINUEDEBOUNCE:

INC DebounceCount ;THEN

JMP ENDDEBOUNCING ;Increment Debounce count, as debounce condition is

;met



RESETEVERYTHING1:

MOV DebounceFlag, False ;ELSE

MOV DebounceCount, Reset ;reset debounce count (as it's in debounce mode)

MOV CurrentKey, EmptyKey ;so there there is no debounced key, and

;JMP ENDDEBOUNCING ;no key being pressed (or acknowledged)



ENDDEBOUNCING: ;ENDIF (for the debounce check)

;JMP ENDDEBOUNCESTATE



ENDDEBOUNCESTATE: ;ENDIF (for the debounce state)

;JMP ENDSCANDEBOUNCE



ENDSCANDEBOUNCE: ;ENDIF (for checking if a new key should

;be scanned for, or the current key

;be debounced)



CHECKDEBOUNCED:

MOV AX, MaxCount ;move MaxCount to be compared

MOV BX, DebounceCount ;move DebounceCount to be compared

CMP AX, BX

JNE CHECKAUTOREPEAT ;IF MaxCount = DebounceCount

;JE SETDEBOUNCED



SETDEBOUNCED:

MOV AL, CurrentKey ;key is debounced

MOV KeyCode, AL ;set keycode

MOV DebounceFlag, True ;set debounce flag to start autorepeating

MOV AX, MaxAutoCount ;MaxCount = MaxAutoCount

MOV MaxCount, AX

;JMP CHECKAUTOREPEAT ;ENDIF



CHECKAUTOREPEAT:

MOV AX, MaxCount ;move MaxCount to be compared

MOV BX, AutoRepeatCount ;move AutoRepeatCount to be compared

CMP AX, BX

JNE ENDALL ;IF MaxCount = AutoRepeatCount THEN

;JE SETREPEATED



SETREPEATED:

MOV AL, CurrentKey ;KeyCode = CurrentKey

MOV KeyCode, AL

MOV DebounceFlag, True ;reset DebounceFlag, AutoRepeatCount

MOV AutoRepeatCount, 0

;JMP ENDALL



ENDALL:

POP DX ;restore registers

POP CX

POP BX

POP AX



RET



SCANDEBOUNCE ENDP









;Table - KeyTable

;The position of the various key names determines the keycode given

;to each key

;4/20/02 Yiyang Gong Initial Revision





KeyTable LABEL BYTE









44

DB Key_Scan_Up ;key code 0

DB Key_Scan_Down ;key code 1

DB Key_Scan_Left ;key code 2

DB Key_Scan_Right ;key code 3

DB Key_Scan_Menu ;key code 4

DB Key_Scan_Illegal ;key code 5



;By the positions of the table setup in keypad.asm

;the keycode of the 5 key system is:

;Key_Up EQU 0

;Key_Down EQU 1

;Key_Left EQU 2

;Key_Right EQU 3

;Key_Menu EQU 4

;Key_Illegal EQU 5





CODE ENDS





;Data segment



DATA SEGMENT PUBLIC 'DATA'





CurrentKey DB ‘?’ ;The current key being scanned for



DebounceFlag DB ‘?’ ;the flag of the status of a key being

debounced



AutoRepeatCount DW ‘?’ ;the count during autorepeating

;to reach the maxcount



DebounceCount DW ‘?’ ;the count during debouncing a key

;to reach the maxcount



MaxCount DW ‘?’ ;the maximum count to reach for debouncing

;or autorepeating



KeyCode DB ‘?’ ;the code to be returned after it is

debouced

;or autorepeated



DATA ENDS





END









45

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; ;

; Keypad (keypad.inc) ;

; Keypad Handler ;

; Include File ;

; ;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;Revision History

;-2/14/02 Initial Revision

;-5/6/02 Revised to work with 5 key system in Oscilloscope

;





MaxDebounceCount EQU 20 ;the number of milliseconds for debouncing a key

MaxAutoCount EQU 300 ;the number of milliseconds to wait for

;autorepeating a key



EmptyKey EQU 01FH ;the empty key (none of the 5 keys pressed - 11111B)



True EQU 1

False EQU 0



Reset EQU 0



Key_Scan_Up EQU 00FH ;the codes for each key pressed

Key_Scan_Down EQU 017H

Key_Scan_Left EQU 01BH

Key_Scan_Right EQU 01DH

Key_Scan_Menu EQU 01EH

Key_Scan_Illegal EQU 000H





;By the positions of the table setup in keypad.asm

;the keycode of the 5 key system is:

;Key_Up EQU 0

;Key_Down EQU 1

;Key_Left EQU 2

;Key_Right EQU 3

;Key_Menu EQU 4

;Key_Illegal EQU 5



PortNumber EQU 0H ;the port to read key presses from



; Timer Defintions



; Addresses

Tmr2Ctrl EQU 0FF66H ;address of Timer 2 Control Register

Tmr2MaxCnt EQU 0FF62H ;address of Timer 2 Max Count A Register

Tmr2Count EQU 0FF60H ;address of Timer 2 Count Register



; Control Register Values



Tmr2CtrlVal EQU 0E021H ;value to write to Timer 2 Control Register

;1--------------- enable timer

;-1-------------- write to control

;--1------------- interrupts

;----------1----- max counts

;---------------1 continuous mode



; Interrupt Vectors

Tmr2Vec EQU 19 ;interrupt vector for Timer 2



; Register Values

INTCtrlrCVal EQU 00001H ;set priority for timers to 1 and enable

Timer0EOI EQU 00008H ;Timer EOI command (same for all timers)







; Timing Definitions

COUNTS_PER_MS EQU 2000 ;number of timer counts per 1 ms







46

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;

; The file for handling putting

; pixels on the LCD (lcd.asm)

;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Clear_Display()

; -This function clears the display (makes all pixels white) by cycling

; through the rows and columns in the appropriate addresses in VRAM and

; writing the clear pixel function

;

;Plot_pixel(x, y, pixel_color)

; - This function plots a specific pixel a specific color. First the function

; finds the appropriate address of VRAM to write to by normalizing everything

; to the first quadrant. At the same time, it finds the required number of

; shifts to shift the pixel value; this pixel value will then be written VRAM

; maintaining the state for the rest of the quad of pixels.

;SwapBuffer()

; - This functions swaps the buffer being displayed and the buffer being written

; to in memory. The two buffer should never be the same block of memory

; at any time.

;ModifyBuffer()

; - This function only changes the buffer being displayed. This function is a

; fix to the problem in one-shot mode where the one-shot trace, as well

; as the one-shot menu is displayed on the hidden buffer. This fix shows

; the hidden buffer

;InitBuffer()

; - This function initializes the position of the buffer to be written to,

; which is not the buffer being displayed

;Author: Yiyang Gong

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Revision History

;- 6/7/02 Initial revision

;- 6/10/02 Added double buffering through the Swapbuffer and ModifyBuffer functions



Name LCD



CGROUP GROUP CODE

DGROUP GROUP DATA



$include(lcd.inc)



EXTRN Key_Available:NEAR



CODE SEGMENT PUBLIC 'CODE'



ASSUME CS:CGROUP, DS:DGROUP



;InitBuffer()

;Description:

; The function clears the LCD display by filling the appropriate

; rows of the VRAM with empty bits (0's).

;Arguments: None

;Return Value: None

;Local Variables: None

;Shared Variables: BaseAddress - the address of the buffer to write to

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Algorithms: None

;Data Structures: None

;Registers Used: None

;Pseudo Code

;BaseAddress is the alternate address

;END

;Revision History

;6/10/02 Yiyang Gong Initial Revision

;Note that this function assumes that the buffer displayed intially

;is the lower block of memory at row 0. This assumption is correct,







47

;as the lattice code starts with the lower block displayed.



InitBuffer PROC NEAR

Public InitBuffer



MOV BaseAddress, AltAddress

RET

InitBuffer ENDP



;void Clear_Display(void)

;Description:

; The function clears the LCD display by filling the appropriate

; rows of the VRAM with empty bits (0's).

;Arguments: None

;Return Value: None

;Local Variables: DX - the row address

; BX - the column address

;Shared Variables: None

;Global Variables: None

;Input: None

;Output: A cleared LCD display

;Error Handling: None

;Algorithms: None

;Data Structures: None

;Registers Used: AX, BX, ES, DI, flags

;Pseudo Code

;Row = 0

;Col = 0

;FOR Col = 0 to 239

;FOR ROW = 0 to 63

; Clear pixel (in all four quadrants)

;ENDFOR

;ENDFOR

;END

;Revision History

;6/7/02 Yiyang Gong Initial Revision



Clear_Display PROC NEAR

Public Clear_Display



PUSH AX ;save the registers

PUSH BX

PUSH ES

PUSH DI



MOV DI, VRAMStartAddr ;use ES as the segment address

MOV ES, DI

XOR AX, AX ;clear AX to use as empty pixel

XOR DI, DI ;BX as column, and DI as row

XOR BX, BX



RowLoop:

MOV ES:[BX+DI], AL ;clear all 4 quadrants

INC DI ;mov to next row

CMP DI, NumRows ;IF DI = 64 THEN

JGE BottomQuads ;pixel is in the bottom quads

JL TopQuads







49

BottomQuads:

SUB AX, NumRows ;adjust the row to be in the top quad

INC CL ;one shift is needed between top and bottom quads

;JMP TopQuads



TopQuads: ;ELSE do nothing ENDIF

CMP BX, NumCols ;IF BX >= 240 THEN

JGE RightQuads ;pixel is in the right quads

JL LeftQuads



RightQuads:

SUB BX, NumCols ;adjust the row to be in the left quad

INC CL ;two shifts are needed between the left and right quads

INC CL



LeftQuads:

ROL BX, OneByte ;Make BX the physical column address (upper byte)

ADD BX, AX ;now make BX the physical RAM address (both bytes)

MOV AX, VRAMStartAddr ;Setup ES as the segment address

MOV ES, AX

CMP DX, Pixel_Black ;If the pixel should be written white

JE PlotThePixel

;JNE CLearThePixel



ClearThePixel: ;THEN

ROL DX, CL ;rotate the clear pixel to the correct position

;(1st-4th bits)

XOR AH, AH ;clear AH for and command later

MOV AL, ES:[BX] ;take in the current quad of pixels

AND AX, DX ;clear the appropriate pixel

MOV ES:[BX], AL ;write back out the quad of pixels

JMP EndPlotPixel



PlotThePixel: ;ELSE

ROL DX, CL ;rotate the black pixel to the correct position

;(1st-4th bits)

XOR AH, AH ;clear AH for and command later

MOV AL, ES:[BX] ;take in the current quad of pixels

OR AX, DX ;make black the appropriate pixel

MOV ES:[BX], AL ;write back out the quad of pixels

;ENDIF

EndPlotPixel:

POP ES ;restore the registers

POP DX

POP CX

POP BX

POP AX

POP BP

RET

Plot_Pixel ENDP





;swapbuffer()

;Description: This functions swaps the buffer being displayed and the buffer being

;written to in memory. The two buffer should never be the same block of memory

;at any time.

;Arguments: None

;Return Value: None

;Local Variables: None

;Shared Variables: BaseAddress - the address block (starting at row 0, or

; row 64) to write to. This assumes that the baseaddresses

; begins at rows 0 and 64

;Global Variables: None

;Input: None

;Output: PCS4, the chip select to swap the buffer to be displayed

; going through the lattice chip

;Error Handling: None

;Algorithms: None

;Data Structures: None

;Registers Used: AX, DX







50

;Known Bugs: There is an error associated with double buffering. When the mainloop goes

;to one-shot mode, the mainloop plots the trace, but never ends the traces. Thus, the

;trace and the menu are both in the hidden buffer during the one-shot mode; the one-shot

;trace is never displayed.

;Pseudo Code

;Change the base address to write to the other block

;(0 to 64, or 64 to 0)

;switch to the other buffer to display

;END



;Revision History

;6/10/02 Yiyang Gong Initial Revision



SwapBuffer PROC NEAR

Public SwapBuffer



PUSH DX ;save registers

PUSH AX



MOV DX, ChangeBufferPort ;set up a command giving PCS4

IN AL, DX ;activate PCS for a read cycle

XOR BaseAddress, AltAddress ;change the base address to be written to

;from 0 to 64 or 64 to 0



POP AX ;restore registers

POP DX

RET

SwapBuffer ENDP





;ModifyBuffer()

;Description: This function only changes the buffer beign displayed. This function is a

; fix to the problem in one-shot mode where the one-shot trace, as well

; as the one-shot menu is displayed on the hidden buffer. This fix shows

; the hidden buffer.

;Arguments: None

;Return Value: None

;Local Variables: None

;Shared Variables: None

;Global Variables: None

;Input: None

;Output: PCS4, the chip select to swap the buffer to be displayed

; going through the lattice chip

;Error Handling: None

;Algorithms: None

;Data Structures: None

;Registers Used: AX, DX

;Known Bugs: This function attempts to resolve the error created by the

;swapbuffer function during double buffering. However, now the error is not drawing the

;one-shot trace. Although the menu is displayed, the plot_trace() function still draws

;the trace to the hidden buffer, and the one-shot trace is displayed after the scope

;returns to normal mode.

;Pseudo Code

;switch to the other buffer to display

;END



;Revision History

;6/10/02 Yiyang Gong Initial Revision



ModifyBuffer PROC NEAR

Public ModifyBuffer



PUSH DX ;save registers

PUSH AX



MOV DX, ChangeBufferPort ;set up a command giving PCS4

IN AL, DX ;activate PCS4 for a read cycle



POP AX ;restore registers

POP DX









51

RET

ModifyBuffer ENDP



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Boot-up Screen

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;The boot up screen requires a main function LScope(), and a helper function

;PlotBox(). However, it's code will not be given as it was written in assembly

;(should not reverse the abstraction and call Plot_line), and required many constants.

;(aka ugly code). Suffice it to say that the function draws a line in on the screen in

;the shape of "LScope" and draws a box around the line for the fill in effect





CODE ENDS





DATA SEGMENT PUBLIC 'DATA'



BaseAddress DW '?' ;the base address for which buffer in memory is

displayed



DATA ENDS



END









52

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

; Include file (lcd.inc)

; for the LCD functions

;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;Revision History

;-6/7/02 initial revision

;









NumRows EQU 64 ;the number of rows per quadrant

NumCols EQU 240 ;the number of columns per quadrant

;Note that by adding 1, these are also the number of rows and columns

;occupied by the screen in VRAM



Pixel_Black EQU 00001H ;The 1 in the first place will be

;rotated left to plot a pixel black

Pixel_White EQU 0FFFEH ;The 0 in the first place will be

;rotated left to plot a pixel white



VRAMStartAddr EQU 4000H ;the starting address of the VRAM

;set by the MMCS value



OneByte EQU 8 ;A one byte shift/rotate is

;equal to a 8 bit shift/rotate



AltAddress EQU 64 ;the starting address of the alternate

;address block (either starting with 0 rows

;or with 64 rows)

ChangeBufferPort EQU 200H ;the PCS4 select line to change the row transfer

;address from the lower block of the buffer

;to the upper block of the buffer









53

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;

; File that handles all the trigger (trigger.asm)

; trigger delays, and subsequent sample transfers

;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;InstallTriggerHandlers()

; The function installs the interrupt handlers for the trigger delay

; (timer0) and the sample transfer (int0) in the interrupt vectors.

;InitTriggerValues()

; Initializes all the trigger variables to their proper

; values. This starts the sample buffer at position 0, resets the

; SampleDoneFlag, and initially masks the interrupt for the sample

; data transfer.

;TriggerDelayHandler()

; This function handles the trigger delay. After

; this timer0 reaches its max count, the interrupt unmasks

; int0 (the data transfer interrupt), to allow data to be transfered

; from the FIFO to memory. This function will also turn the

; timer0 interrupt off (so that not a another delay is recorded

; for the one call to start_sample).

;SampleDataHandler()

; This function will take in the samples from the FIFO

; after its interrupt is enabled. The interrupt is from the empty

; pin of the FIFO; when the FIFO is not empty, the interrupt

; will occur.

;;InitTriggerTimer()

; This function will take in the samples from the FIFO

; after its interrupt is enabled. The interrupt is from the empty

; pin of the FIFO; when the FIFO is not empty, the interrupt

; will occur.

;void Start_Sample(void)

; This function will immediately start taking samples.

; Because of the PLD design, the trigger value must be put out to the

; PLD before taking any sample. Thus, the saved current trigger (given

; by the last call to set_trigger()) will be given, and then the timer0

; that handles the trigger delay will be enabled to count the

; number of samples needed to delay by, once the sample is triggered.

;;void Set_Sample_Rate(long int number_of_samples)

; This function set the sample rate (i.e. the frequency of timer 1) of the scope.

; It will do so by converting the require number of samples to a count on timer 1.

;unsigned char far *sample_done(void)

; If the current sample is done, then return a far pointer to the

; where the sample is (in the sample buffer) in DX|AX. If the current sample

; is not done, return NULL in DX|AX.

;void set_trigger(int level, int slope)

; The function sets the trigger level by converting the level and

; slope into a single number and outputting that number to the PLD.

; The PLD will then remember trigger for one sample. The function will also

; save the current trigger (the last trigger to the call of set_trigger()).

;void set_delay(long int number_of_samples)

; The function will set the delay (in number of samples) for the trigger.

; The number of samples will be directly written to the timer0 maxcount,

; as timer1 counts the number samples to delay by.

;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Revision History

;-5/23/02 Initial revision of all functions

;-5/24/02 Started using the interrupt mask register to mask Int0

;-5/25/02 fixed error with set sample rate with minimun sample delay as 0

; this means that the minimum sample rate is actually 65535

;-6/1/02 turn off the sample timer when attempting to find the trigger

; in calling start_sample() to get a more accurate trigger

;

Name TriggerHandler



CGROUP GROUP CODE

DGROUP GROUP DATA



$include(trigger.inc)







54

CODE SEGMENT PUBLIC 'CODE'



ASSUME CS:CGROUP, DS:DGROUP







;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;InstallTriggerhandlers

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: Installs the interrupt handlers for the triggerdelay (timer0) and

; the sample transfer (int0) from the FIFO.

;Arguments: None

;Return value: None

;Local Variables: None

;Shared Variables: None

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, ES

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;Put Handler for SampleTransfer in Int0 vector

;Put Handler for TriggerDelay in Timer0

;END

;Revision History

; -5/23/02 Initial Revision



InstallTriggerHandlers PROC NEAR

Public InstallTriggerHandlers



PUSH ES ;save registers

PUSH AX



XOR AX, AX ;clear ES (interrupt vectors are in segment 0)

MOV ES, AX

;store the vector for the 2 interrupts used



MOV ES: WORD PTR (4 * Int0Vec), OFFSET(SampleDataHandler)

;int0 - sample transfer

MOV ES: WORD PTR (4 * Int0Vec + 2), SEG(SampleDataHandler)



MOV ES: WORD PTR (4 * Tmr0Vec), OFFSET(TriggerDelayHandler)

;timer0 - sample delay

MOV ES: WORD PTR (4 * Tmr0Vec + 2), SEG(TriggerDelayHandler)



POP AX ;restore registers

POP ES

RET ;all done, return

InstallTriggerHandlers ENDP





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;InitTriggerValues()

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: Initializes all the trigger variables to their proper

; values. This starts the sample buffer at position 0, resets the

; SampleDoneFlag, and initially masks the interrupt for the sample

; data transfer.

;Arguments: None

;Return value: None

;Local Variables: None

;Shared Variables: BufferPosition - the position to write to in the buffer

; SampleDoneFlag – the status for finished taking in a sample

;Global Variables: None

;Input: None







55

;Output: None

;Error Handling: None

;Registers used: AX, DX

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;Start buffer at position 0

;reset the sampledone flag

;mask int0 (the sample transfer interrupt)

;END

;Revision History

; -5/23/02 Yiyang Gong Initial Revision

; -5/24/02 Yiyang Gong Used interrupt mask register



InitTriggerValues PROC NEAR

Public InitTriggerValues



PUSH AX ;save registers

PUSH DX



MOV BufferPosition, Start ;start the buffer at position 0

MOV SampleDoneFlag, Null ;reset the sampledoneflag



MOV DX, Int0CtrlAddr ;initializes the sample

MOV AX, Int0CtrlVal ;transfer interrupts

OUT DX, AL



MOV DX, IntMaskAddr ;start with Int0 masked

IN AL, DX ;by setting the bit for int0

OR AL, StopInt0 ;in the interrupt mask register

OUT DX, AL



MOV DX, FIFOResetPort ;reset the fifo

IN AL, DX



POP DX ;restore Registers

POP AX



RET

InitTriggerValues ENDP



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;TriggerDelayHandler()

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: This function handles the trigger delay. After

; this timer reaches its max count, the interrupt unmasks

; int0 (the data transfer interrupt), to allow data to be transfered

; from the FIFO to memory. This function will also turn the

; timer0 interrupt off (so that not a another delay is recorded

; for the one call to start_sample).

;Arguments: None

;Return value: None

;Local Variables: None

;Shared Variables: None

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, DX

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

; Allow int0 interrupts (start the data transfers)

; Disable timer0

; Send EOI

; END

;Revision History







56

; -5/23/02 Yiyang Gong Initial Revision



TriggerDelayHandler PROC NEAR ;FOR Timer0, after the trigger

Public TriggerDelayHandler



PUSH AX ;save registers

PUSH DX



MOV DX, IntMaskAddr ;after the trigger, the int0 (from FIFO)

IN AL, DX ;is enabled to take the data

AND AL, AllowInt0 ;by unmasking the interrupt

OUT DX, AL



MOV DX, Tmr0CtrlAddr ;the timer0 interrupt is then

IN AX, DX ;disable by reseting the

OR AX, WriteEnableTmr0 ;enable write to timer 0 register

AND AX, DisableTmr0 ;disable timer0 to stop all trigger delays\

;after this

OUT DX, AL



MOV DX, INTCtrlEOI ;send the EOI to the interrupt controller

MOV AX, Timer0EOI

OUT DX, AL

POP DX ;restore registers

POP AX



IRET

TriggerDelayHandler ENDP





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;SampleDataHandler()

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: This function will take in the samples from the FIFO

; after its interrupt is enabled. The interrupt is from the empty

; pin of the FIFO; when the FIFO is not empty, the interrupt

; will occur.

;Arguments: None

;Return value: None

;Local Variables: None

;Shared Variables: BufferPosition - The current position of the sample buffer

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, BX, DX, flags

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;Take in sample from the FIFO

;move sample to sample buffer

;move to next buffer position

;IF Enough Samples have been taken THEN

;turn off INT0 by masking it

;ELSE do nothing

;ENDIF

;send EOI

;END

;Revision History

; -5/23/02 Yiyang Gong Initial Revision



SampleDataHandler PROC NEAR ;From EF of FIFO

Public SampleDataHandler



PUSH AX ;save registers

PUSH BX

PUSH DX



MOV DX, FIFOPort ;move the to get the data from







57

IN AL, DX ;get the data from the FIFO



MOV BX, Offset(SampleBuffer) ;move the pointer to the

ADD BX, BufferPosition ;correct position in the samplebuffer

MOV [BX], AL ;transfer the data into the samplebuffer



INC BufferPosition ;move the bufferposition into the next place

CMP BufferPosition, SampleLength ;check if enough samples have been collected

JNE NoMoreSamplesTaken ;IF not enough THEN end handler

;JE StopRecognizingSamples



StopRecognizingSamples: ;ELSE

MOV DX, IntMaskAddr ;turn off Int0

IN AL, DX ;by masking the int0 bit in the IntMask

register

OR AX, StopInt0

OUT DX, AL



MOV SampleDoneFlag, NOT(Null) ;also set the sampledone flag

;JMP NoMoreSamplesTaken



NoMoreSamplesTaken: ;ENDIF

MOV DX, IntCtrlEOI ;send the EOI to the interrupt controller

MOV AX, Int0EOI

OUT DX, AL



POP DX ;restore registers

POP BX

POP AX



IRET

SampleDataHandler ENDP









;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;InitTriggerTimer()

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: This function will take in the samples from the FIFO

; after its interrupt is enabled. The interrupt is from the empty

; pin of the FIFO; when the FIFO is not empty, the interrupt

; will occur.

;Arguments: None

;Return value: None

;Local Variables: None

;Shared Variables: None

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, DX

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;Setup timer0, for the number of sample delays

;Setup timer0, for no initial interrupts

;Setup timer1, for sampling frequency

;Setup timer1, for no interrupts (ever), running continuously

;Setup timerinterrupt priorities

;END

;Revision History

; -5/23/02 Yiyang Gong Initial Revision





InitTriggerTimer PROC NEAR

Public InitTriggerTimer







58

PUSH DX ;save registers

PUSH AX



MOV DX, Tmr0CountAddr ;initialize the count register to 0

XOR AX, AX

OUT DX, AL



MOV DX, Tmr0MaxCountAddr ;setup max count for number of sample delays

MOV AX, Tmr0MaxCountVal

OUT DX, AL



MOV DX, Tmr0CtrlAddr ;setup the control register, no interrupts

MOV AX, Tmr0CtrlVal ;single run mode

OUT DX, AL



MOV DX, Tmr1Count ;initialize the count register to 0

XOR AX, AX

OUT DX, AL



MOV DX, Tmr1MaxCountAddr ;setup max count for 1ms counts

MOV AX, Tmr1MaxCountVal

OUT DX, AL



MOV DX, Tmr1CtrlAddr ;setup the control register, no interrupts

MOV AX, Tmr1CtrlVal ;continuously running

OUT DX, AL





MOV DX, INTTmrCtrlAddr ;setup the interrupt control register

MOV AX, INTTmrCtrlVal ;timers are set to 1 as priority

OUT DX, AL



MOV DX, INTCtrlEOI ;send a non-specific EOI (to clear out controller)

MOV AX, NonSpecEOI

OUT DX, AL



POP AX ;restore registers

POP DX



RET ;done so return



InitTriggerTimer ENDP







;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;void Start_Sample(void)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: This function will immediately start taking samples.

; Because of the PLD design, the trigger value must be put out to the

; PLD before taking any sample. Thus, the saved current trigger (given

; by the last call to set_trigger()) will be given, and then the timer0

; that handles the trigger delay will be enabled to count the

; number of samples needed to delay by, once the sample is triggered.

;Arguments: None

;Return value: None

;Local Variables: None

;Shared Variables: CurrentTrigger - The current trigger value to be outputted

; the PLD

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, DX

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;turn off timer1 to stop any sample from triggering







59

;give trigger value

;enable timer0

;enable timer1 to let a trigger be found

;END

;Revision History

;-5/23/02 Yiyang Gong Initial Revision

;-6/1/02 Yiyang Gong disabled timer1 when finding a trigger - gets a more

; accurate trigger (close to trigger value)





Start_Sample PROC NEAR

Public Start_Sample



PUSH AX ;save registers

PUSH DX



MOV DX, Tmr1CtrlAddr ;look at timer1 controller

IN AL, DX

AND AX, TurnOffTmr1 ;turn off the timer1

OR AX, EnableWriteTmr1 ;and its interrupt

OUT DX, AL



MOV AL, CurrentTrigger ;get the current trigger value

MOV DX, TriggerValuePort ;and output it again

OUT DX, AL



MOV DX, Tmr0CtrlAddr ;mov in the timer0 control address to enable it

IN AL, DX ;take in current state of timer0

OR AX, EnableTmr0 ;enable the timer

OUT DX, AL ;write the enable value back out



MOV DX, Tmr1CtrlAddr ;take the timer1 controller

IN AL, DX ;turn on the timer

OR AX, TurnOnTmr1 ;with interrupts off

AND AX, Tmr1IntOff ;to allow for a trigger to be found

OUT DX, AL ;by the lattice



POP DX ;restore registers

POP AX

RET

Start_Sample ENDP





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;int Set_Sample_Rate(long int number_of_samples)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: This function set the sample rate (i.e. the frequency of timer 1) of the

;scope. It will do so by converting the require number of samples to a count on timer 1.

;Arguments: None

;Return value: samples (AX) - the number of samples that will be taken at that

; sample rate

;Local Variables: None

;Shared Variables: None

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, BX, DX, BP

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;divide 1 Megahertz by the number of samples required per second

;the number * 2 is the number counts needed

;write the number of counts to the timer1 max counts

;return the appropriate number of samples that will be taken

;END

;Revision History

; -5/23/02 Yiyang Gong Initial Revision









60

;where the long int is located on the stack

RateHighAddr EQU 6

RateLowAddr EQU 4



Set_Sample_Rate PROC NEAR

Public Set_Sample_Rate



PUSH BP

MOV BP, SP



PUSH BX ;save registers

PUSH DX





MOV AX, [BP+RateLowAddr] ;retrieve the low word of the rate

MOV DX, [BP+RateHighAddr] ;retrieve the high word of the rate



Scaler:

MOV BX, Scaler50 ;move 50 as a scaler into BX

DIV BX ;divide the number of samples by 50

MOV BX, AX

;the formula is:

;1*10^6/x = (1*10^6/50)/(x/50)

;as x is a minimum of 50 at 20ms



XOR DX, DX ;clear DX for second division

MOV AX, OneMegScale50 ;divide with the 1MHz value also scaled down by 50

DIV BX ;get the counts in Ax



ADD AX, AX ;Doubles the number of samples

;(for internal 2 MHz clock)

MOV BX, AX ;saves number of samples





MOV DX, Tmr1MaxCountAddr ;Actually sets the frequency

OUT DX, AL



MOV AX, SampleLength ;returns number of samples to be taken

;(always constant)

POP DX

POP BX

POP BP

RET

Set_Sample_Rate ENDP







;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;unsigned char far *sample_done(void)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: If the current sample is done, then return a far pointer to the

; where the sample is (in the sample buffer) in DX|AX. If the current sample

; is not done, return NULL in DX|AX.

;Arguments: None

;Return value: a 32-bit pointer in DX|AX

;Local Variables: None

;Shared Variables: SampleDoneFlag - If set, the sample is done

; if reset, the sample is not done

; BufferPosition – is reset to the start with new sample

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, DX

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;IF SampleDoneFlag = set THEN

; mov samplebuffer address into DX|AX







61

; reset sampledoneflag

; reset samplebuffer, bufferposition

;ELSE

; mov Null into DX|AX

;ENDIF

;END

;Revision History

; -5/23/02 Yiyang Gong Initial Revision



Sample_Done PROC NEAR

Public Sample_Done



CMP SampleDoneFlag, Null ;IF SampleDone = set THEN

JE SampleNotYetDone

;JNE SampleIsDone



SampleIsDone: ;THEN

MOV AX, Offset(SampleBuffer) ;mov samplebuffer address into DX|AX

MOV DX, Seg(SampleBuffer)

MOV BufferPosition, Start ;reset bufferposition

MOV SampleDoneFlag, Null ;sampledone is acknowledged and reset

JMP SampleDoneEnd



SampleNotYetDone: ;ELSE

MOV AX, Null ;mov NULL into DX|AX

MOV DX, Null

;JMP SampleDoneEnd ;ENDIF



SampleDoneEnd:

RET

Sample_Done ENDP







;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;void set_trigger(int level, int slope)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: The function sets the trigger level by converting the level and

; slope into a single number and outputting that number to the PLD.

; The PLD will then remember trigger for one sample. The function will also

; save the current trigger (the last trigger to the call of set_trigger()).

;Arguments: level - the level at which the sample triggers (0 - 127)

; slope - + or - slope to trigger on

; both are passed on the stack

;Return value: None

;Local Variables: None

;Shared Variables: CurrentTrigger – this variable is saved with every

; call to this function

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, BX, DX, BP

;Algorithms: None

;Data Structures: trigger - the upper 7 bits are the level

; the lower bit is the slope (0 is positive slope, 1 is negative)

;Known bugs: None

;Limitations: None

;Pseudo code

;get the level and the slope

;convert the level and slope into one number

;output the number to the PLD

;END

;Revision History

; -5/23/02 Yiyang Gong Initial Revision



;where on the stack the arguements are located

LevelAddr EQU 4

SlopeAddr EQU 6



;void set_trigger(int level, int slope)







62

Set_Trigger PROC NEAR

Public Set_Trigger



PUSH BP ;save BP



MOV BP, SP ;use BP to retrieve arguments off the stack



PUSH AX ;save registers

PUSH BX

PUSH DX



MOV AX, [BP+LevelAddr] ;AX = slope

MOV BX, [BP+SlopeAddr] ;BX = level



SHL AX, 1 ;because slope is only 7 bits, shift to the

;upper seven bits

OR AX, BX ;let the level occupied the last bit



MOV CurrentTrigger, AL ;save the current trigger for

;multiple samples later samples



MOV DX, TriggerValuePort ;write the value to the PLD

OUT DX, AL



POP DX ;restore registers

POP BX

POP AX

POP BP

RET

Set_Trigger ENDP





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;void set_delay(long int number_of_samples)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Description: The function will set the delay (in number of samples) for the trigger.

; The number of samples will be directly written to the timer0 maxcount,

; as timer1 counts the number samples to delay by.

;Arguments: number_of_samples - 32-bits passed on the stack

;Return value: None

;Local Variables: None

;Shared Variables: None

;Global Variables: None

;Input: None

;Output: None

;Error Handling: None

;Registers used: AX, DX, BP

;Algorithms: None

;Data Structures: None

;Known bugs: None

;Limitations: None

;Pseudo code

;Write delay into timer0 maxcount

;END

;Revision History

; -5/23/02 Yiyang Gong Initial Revision



;where the arguments are located on the stack

DelayLowAddr EQU 4

DelayHighAddr EQU 6



Set_Delay PROC NEAR

Public Set_Delay



PUSH BP ;save BP

MOV BP, SP ;use BP to retrieve arguments on stack



PUSH AX ;save registers

PUSH DX

;Assume that the trigger delay is 0

or key is pressed for a menu item. Also included are the functions

for displaying the current menu option selection. The functions included

are:

display_mode - display trigger mode

display_scale - display the scale type

display_sweep - display the sweep rate

display_trg_delay - display the tigger delay

display_trg_level - display the trigger level

display_trg_slope - display the trigger slope

mode_toggle - toggle the mode between "Normal" and "One-Shot"

no_display - nothing to display for option setting

no_menu_action - no action to perform for or key

scale_toggle - toggle the scale type

set_scale - set the scale type

set_sweep - set the sweep rate

set_trg_delay - set the tigger delay

set_trg_level - set the trigger level

set_trg_slope - set the trigger slope

set_trigger_mode - set the trigger mode

sweep_down - decrease the sweep rate

sweep_up - increase the sweep rate

trg_delay_down - decrease the trigger delay

trg_delay_up - increase the trigger delay

trg_level_down - decrease the trigger level

trg_level_up - increase the trigger level

trg_slope_toggle - toggle the trigger slope between "+" and "-"



The local functions included are:

adjust_trg_delay - adjust the trigger delay for a new sweep rate

cvt_num_field - converts a numeric field value to a string



The locally global variable definitions included are:

delay - current trigger delay

level - current trigger level

scale - current display scale type

slope - current trigger slope

sweep - current sweep rate

sweep_rates - table of information on possible sweep rates

trigger_mode - current triggering mode





Revision History

3/8/94 Glen George Initial revision.

3/13/94 Glen George Updated comments.

3/13/94 Glen George Changed all arrays of constant strings to be

static so compiler generates correct code.

3/13/94 Glen George Changed scale to type enum scale_type and

output the selection as "None" or "Axes".

This will allow for easier future expansion.

3/13/94 Glen George Changed name of set_axes function (in

tracutil.c) to set_display_scale.

3/10/95 Glen George Changed calculation of displayed trigger

level to use constants MIN_TRG_LEVEL_SET and

MAX_TRG_LEVEL_SET to get the trigger level

range.

3/17/97 Glen George Updated comments.

6/13/02 Yiyang Gong Changed the mode_toggle() function, so that

double buffering shows at least the menu

in one-shot mode. Also added 1us sampling







67

in the sweep rates

*/







/* library include files */

/* none */



/* local include files */

#include "interfac.h"

#include "scopedef.h"

#include "lcdout.h"

#include "menuact.h"

#include "tracutil.h"









/* local function declarations */

void adjust_trg_delay(int, int); /* adjust the trigger delay for new sweep */

void cvt_num_field(long int, char *); /* convert a number to a string */









/* locally global variables



/* trace parameters */

static enum trigger_type trigger_mode; /* current triggering mode */

static enum scale_type scale; /* current scale type */

static int sweep; /* sweep rate index */

static int level; /* current trigger level */

static enum slope_type slope; /* current trigger slope */

static long int delay; /* current trigger delay */



/* sweep rate information */

static const struct sweep_info sweep_rates[] =

{ {1000000L, " 1 \004s "}, /* added for 1Mhz sampling*/

{ 500000L, " 2 \004s " },

{ 200000L, " 5 \004s " },

{ 100000L, " 10 \004s " },

{ 50000L, " 20 \004s " },

{ 20000L, " 50 \004s " },

{ 10000L, " 100 \004s" },

{ 5000L, " 200 \004s" },

{ 2000L, " 500 \004s" },

{ 1000L, " 1 ms " },

{ 500L, " 2 ms " },

{ 200L, " 5 ms " },

{ 100L, " 10 ms " },

{ 50L, " 20 ms " } };









/*

no_menu_action



Description: This function handles a menu action when there is nothing

to be done. It just returns.



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.







68

Global Variables: None.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void no_menu_action()

{

/* variables */

/* none */







/* nothing to do - return */

return;



}









/*

no_display



Description: This function handles displaying a menu option's setting

when there is nothing to display. It just returns,

ignoring all arguments.



Arguments: x_pos (int) - x position (in character cells) at which to

display the menu option (not used).

y_pos (int) - y position (in character cells) at which to

display the menu option (not used).

style (int) - style with which to display the menu option

(not used).

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: None.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void no_display(int x_pos, int y_pos, int style)

{

/* variables */

/* none */







/* nothing to do - return */

return;



}









/*

set_trigger_mode









69

Description: This function sets the triggering mode to the passed

value.



Arguments: m (enum trigger_type) - mode to which to set the

triggering mode.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: trigger_mode - initialized to the passed value.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void set_trigger_mode(enum trigger_type m)

{

/* variables */

/* none */







/* set the trigger mode */

trigger_mode = m;



/* set the new mode */

set_mode(trigger_mode);





/* all done setting the trigger mode - return */

return;



}









/*

mode_toggle



Description: This function handles toggling (and setting) the current

triggering mode.



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: trigger_mode - toggled.



Author: Glen George, Yiyang Gong

Last Modified: 6/13/02 - Changed to allow double

buffering to show a workable menu

in one shot mode



*/



void mode_toggle()







70

{

/* variables */

/* none */







/* toggle the trigger mode */

if (trigger_mode == NORMAL_TRIGGER)

trigger_mode = ONESHOT_TRIGGER;

else

trigger_mode = NORMAL_TRIGGER;





modifybuffer();

/* set the new mode */

set_mode(trigger_mode); /* change to the modified buffer

to show a working menu during

one-shot mode. When the mode returns

to normal, the correct buffer is

then switched back */





/* all done with the trigger mode - return */

return;



}









/*

display_mode



Description: This function displays the current triggering mode at the

passed position, in the passed style.



Arguments: x_pos (int) - x position (in character cells) at which to

display the trigger mode.

y_pos (int) - y position (in character cells) at which to

display the trigger mode.

style (int) - style with which to display the trigger

mode.

Return Value: None.



Input: None.

Output: The trigger mode is displayed at the passed position on

the screen.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: trigger_mode - determines which string is displayed.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void display_mode(int x_pos, int y_pos, int style)

{

/* variables */



/* the mode strings (must match enumerated type) */

const static char * const modes[] = { " Normal ", " One-Shot" };







/* display the trigger mode */

plot_string(x_pos, y_pos, modes[trigger_mode], style);







71

/* all done displaying the trigger mode - return */

return;



}









/*

set_scale



Description: This function sets the scale type to the passed value.



Arguments: s (enum scale_type) - scale type to which to initialize

the scale status.

Return Value: None.



Input: None.

Output: The new trace display is updated with the new scale.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: scale - initialized to the passed value.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void set_scale(enum scale_type s)

{

/* variables */

/* none */







/* set the scale type */

scale = s;



/* output the scale appropriately */

set_display_scale(scale);





/* all done setting the scale type - return */

return;



}









/*

scale_toggle



Description: This function handles toggling (and setting) the current

scale type.



Arguments: None.

Return Value: None.



Input: None.

Output: The new scale is output to the trace display.



Error Handling: None.



Algorithms: None.







72

Data Structures: None.



Global Variables: scale - toggled.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void scale_toggle()

{

/* variables */

/* none */







/* toggle the scale status */

if (scale == SCALE_NONE)

scale = SCALE_AXES;

else

scale = SCALE_NONE;



/* set the scale type */

set_display_scale(scale);





/* all done with toggling the scale type - return */

return;



}









/*

display_scale



Description: This function displays the current scale type at the

passed position, in the passed style.



Arguments: x_pos (int) - x position (in character cells) at which to

display the scale type.

y_pos (int) - y position (in character cells) at which to

display the scale type.

style (int) - style with which to display the scale type.

Return Value: None.



Input: None.

Output: The scale type is displayed at the passed position on the

display.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: scale - determines which string is displayed.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void display_scale(int x_pos, int y_pos, int style)

{

/* variables */



/* the scale type strings (must match enumerated type) */

const static char * const scale_stat[] = { " None", " Axes" };









73

/* display the scale status */

plot_string(x_pos, y_pos, scale_stat[scale], style);





/* all done displaying the scale status - return */

return;



}









/*

set_sweep



Description: This function sets the sweep rate to the passed value.

The passed value gives the sweep rate to choose from the

list of sweep rates (it gives the list index).



Arguments: s (int) - index into the list of sweep rates to which to

set the current sweep rate.

Return Value: None.



Input: None.

Output: None.



Error Handling: The passed index is not checked for validity.



Algorithms: None.

Data Structures: None.



Global Variables: sweep - initialized to the passed value.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void set_sweep(int s)

{

/* variables */

int sample_size; /* sample size for this sweep rate */







/* set the new sweep rate */

sweep = s;



/* set the sweep rate for the hardware */

sample_size = set_sample_rate(sweep_rates[sweep].sample_rate);

/* also set the sample size for the trace capture */

set_trace_size(sample_size);





/* all done initializing the sweep rate - return */

return;



}









/*

sweep_down



Description: This function handles decreasing the current sweep rate.

The new sweep rate (and sample size) is sent to the

hardware (and trace routines). If an attempt is made to

lower the sweep rate below the minimum value it is not

changed. This routine also updates the sweep delay based







74

on the new sweep rate (to keep the delay time constant).



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: sweep - decremented if not already 0.

delay - increased to keep delay time constant.



Known Bugs: The updated delay time is not displayed. Since the time

is typically only rounded to the new sample rate, this is

not a major problem.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void sweep_down()

{

/* variables */

int sample_size; /* sample size for the new sweep rate */







/* decrease the sweep rate, if not already the minimum */

if (sweep > 0) {

/* not at minimum, adjust delay for new sweep */

adjust_trg_delay(sweep, (sweep - 1));

/* now set new sweep rate */

sweep--;

}



/* set the sweep rate for the hardware */

sample_size = set_sample_rate(sweep_rates[sweep].sample_rate);

/* also set the sample size for the trace capture */

set_trace_size(sample_size);





/* all done with lowering the sweep rate - return */

return;



}









/*

sweep_up



Description: This function handles increasing the current sweep rate.

The new sweep rate (and sample size) is sent to the

hardware (and trace routines). If an attempt is made to

raise the sweep rate above the maximum value it is not

changed. This routine also updates the sweep delay based

on the new sweep rate (to keep the delay time constant).



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.







75

Algorithms: None.

Data Structures: None.



Global Variables: sweep - incremented if not already the maximum value.

delay - decreased to keep delay time constant.



Known Bugs: The updated delay time is not displayed. Since the time

is typically only rounded to the new sample rate, this is

not a major problem.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void sweep_up()

{

/* variables */

int sample_size; /* sample size for the new sweep rate */







/* increase the sweep rate, if not already the maximum */

if (sweep MIN_TRG_LEVEL_SET)

level--;



/* set the trigger level for the hardware */

set_trigger(level, slope);





/* all done with lowering the trigger level - return */

return;



}









/*

trg_level_up



Description: This function handles increasing the current trigger

level. The new trigger level is sent to the hardware.

If an attempt is made to raise the trigger level above

the maximum value it is not changed.



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: level - incremented if not already the maximum value.



Author: Glen George

Last Modified: Mar. 8, 1994



*/









78

void trg_level_up()

{

/* variables */

/* none */







/* increase the trigger level, if not already the maximum */

if (level MIN_DELAY)

delay--;



/* set the trigger delay for the hardware */

set_delay(delay);





/* all done with lowering the trigger delay - return */

return;



}









/*

trg_delay_up



Description: This function handles increasing the current trigger

delay. The new trigger delay is sent to the hardware.

If an attempt is made to raise the trigger delay above

the maximum value it is not changed.



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: delay - incremented if not already the maximum value.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void trg_delay_up()

{

/* variables */

/* none */









83

/* increase the trigger delay, if not already the maximum */

if (delay MAX_DELAY)

/* delay is too large - set to maximum */







84

delay = MAX_DELAY;

if (delay -1000000)) {

/* delay is in milliseconds */

delay_str[7] = 'm';

delay_str[8] = 's';

}

else if ((d -1000000000)) {

/* delay is in seconds */

delay_str[7] = 's';







85

}

else {

/* delay is in kiloseconds */

delay_str[7] = 'k';

delay_str[8] = 's';

}





/* now actually display the trigger delay */

plot_string(x_pos, y_pos, delay_str, style);





/* all done displaying the trigger delay - return */

return;



}









/*

cvt_num_field



Description: This function converts the passed number (numeric field

value) to a string and returns that in the passed string

reference. The number may be signed, and a sign (+ or -)

is always generated. The number is assumed to have three

digits to the right of the decimal point. Only the four

most significant digits of the number are displayed and

the decimal point is shifted appropriately. (Four digits

are always generated by the function).



Arguments: n (long int) - numeric field value to convert.

s (char *) - pointer to string in which to return the

converted field value.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: The algorithm used assumes four (4) digits are being

converted.

Data Structures: None.



Global Variables: None.



Known Bugs: If the passed long int is the largest negative long int,

the function will display garbage.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



static void cvt_num_field(long int n, char *s)

{

/* variables */

int dp = 3; /* digits to right of decimal point */

int d; /* digit weight (power of 10) */



int i = 0; /* string index */







/* first get the sign (and make n positive for conversion) */

if (n 9999) {

/* have more than 4 digits - get rid of one */

n /= 10;

/* adjust the decimal point */

dp--;

}



/* if decimal point is non-positive, make positive */

/* (assume will take care of adjustment with output units in this case) */

while (dp 0; d /= 10) {



/* check if need decimal the decimal point now */

if (dp-- == 0)

/* time for decimal point */

s[i++] = '.';



/* get and convert this digit */

s[i++] = (n / d) + '0';

/* remove this digit from n */

n %= d;

}





/* all done converting the number, return */

return;



}









87

/****************************************************************************/

/* */

/* TRACUTIL (tracutil.c) */

/* Trace Utility Functions */

/* Digital Oscilloscope Project */

/* EE/CS 52 */

/* */

/****************************************************************************/



/*

This file contains the utility functions for handling traces (capturing

and displaying data) for the Digital Oscilloscope project. The functions

included are:

clear_saved_areas - clear all the save areas

do_trace - start a trace

init_trace - initialize the trace routines

plot_trace - plot a trace (sampled data)

restore_menu_trace - restore the saved area under the menus

restore_trace - restore the saved area of a trace

set_display_scale - set the type of displayed scale (and display it)

set_mode - set the triggering mode

set_save_area - determine an area of a trace to save

set_trace_size - set the number of samples in a trace

trace_done - inform this module that a trace has been completed

trace_rdy - determine if system is ready to start another trace

trace_rearm - re-enable tracing (in one-shot triggering mode)



The local functions included are:

none



The locally global variable definitions included are:

cur_scale - current scale type

normal_trg - the current triggering mode (TRUE: normal triggering)

sample_size - the size of the sample for the trace

sampling - currently doing a sample

saved_area - saved trace under a specified area

saved_axis_x - saved trace under the x-axis

saved_axis_y - saved trace under the y-axis

saved_menu - saved trace under the menu

saved_pos_x - starting position (x coorindate) of area to save

saved_pos_y - starting position (y coorindate) of area to save

saved_end_x - ending position (x coorindate) of area to save

saved_end_y - ending position (y coorindate) of area to save

trace_status - whether or not ready to start another trace





Revision History

3/8/94 Glen George Initial revision.

3/13/94 Glen George Updated comments.

3/13/94 Glen George Fixed inversion of signal in plot_trace.

3/13/94 Glen George Added sampling flag and changed the functions

init_trace, do_trace and trace_done to update

the flag. Also the function trace_rdy now

uses it. The function set_mode was updated

to always say a trace is ready for normal

triggering.

3/13/94 Glen George Fixed bug in trace restoring due to operator

misuse (&& instead of &) in the functions

set_axes, restore_menu_trace, and

restore_trace.

3/13/94 Glen George Fixed bug in trace restoring due to the clear

function (clear_saved_areas) not clearing all

of the menu area.

3/13/94 Glen George Fixed comparison bug when saving traces in

plot_trace.

3/13/94 Glen George Changed name of set_axes to set_display_scale

and the name of axes_state to cur_scale to

more accurately reflect the function/variable

use (especially if add scale display types).

3/17/97 Glen George Updated comments.

3/17/97 Glen George Changed set_display_scale to use plot_hline







88

and plot_vline functions to output axes.

6/11/02 Yiyang Gong placed a swapbuffer function at the end of plot trace

so that every time a trace is completed, the buffer

to be displayed is switched, allowing double

buffering.

*/







/* library include files */

/* none */



/* local include files */

#include "scopedef.h"

#include "lcdout.h"

#include "menu.h"

#include "menuact.h"

#include "tracutil.h"









/* locally global variables */



static int normal_trg; /* TRUE for normal triggering */

static int trace_status; /* ready to start another trace */



static int sampling; /* currently sampling data */



static int sample_size; /* number of data points in a sample */



static enum scale_type cur_scale; /* current display scale type */



/* traces (sampled data) saved under the axes */

static unsigned char saved_axis_x[SIZE_X/8]; /* saved trace under x-axis */

static unsigned char saved_axis_y[SIZE_Y/8]; /* saved trace under y-axis */



/* traces (sampled data) saved under the menu */

static unsigned char saved_menu[MENU_SIZE_Y][(MENU_SIZE_X + 7)/8];



/* traces (sampled data) saved under any area */

static unsigned char saved_area[SAVE_SIZE_Y][SAVE_SIZE_X/8]; /* saved trace under any

area */

static int saved_pos_x; /* starting x position of saved area */

static int saved_pos_y; /* starting y position of saved area */

static int saved_end_x; /* ending x position of saved area */

static int saved_end_y; /* ending y position of saved area */









/*

init_trace



Description: This function initializes all of the locally global

variables used by these routines. The saved areas are

set to non-existant with cleared saved data. Normal

normal triggering is set, the system is ready for a

trace, the scale is turned off and the sample size is set

to the screen size.



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.







89

Global Variables: normal_trg - set to TRUE.

trace_status - set to TRUE.

sampling - set to FALSE.

cur_scale - set to SCALE_NONE (no displayed scale).

sample_size - set to screen size (SIZE_X).

saved_axis_x - cleared.

saved_axis_y - cleared.

saved_menu - cleared.

saved_area - cleared.

saved_pos_x - set to off-screen.

saved_pos_y - set to off-screen.

saved_end_x - set to off-screen.

saved_end_y - set to off-screen.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void init_trace()

{

/* variables */

/* none */







/* initialize system status variables */



/* turn on normal triggering */

normal_trg = TRUE;



/* ready for a trace */

trace_status = TRUE;



/* not currently sampling data */

sampling = FALSE;



/* turn off the displayed scale */

cur_scale = SCALE_NONE;



/* sample size is the screen size */

sample_size = SIZE_X;





/* clear save areas */

clear_saved_areas();



/* also clear the general saved area location variables (off-screen) */

saved_pos_x = SIZE_X + 1;

saved_pos_y = SIZE_Y + 1;

saved_end_x = SIZE_X + 1;

saved_end_y = SIZE_Y + 1;





/* done initializing, return */

return;



}









/*

set_mode



Description: This function sets the locally global triggering mode

based on the passed value (TRUE for normal triggering,

FALSE otherwise). The triggering mode is used to

determine when the system is ready for another trace.









90

Arguments: trigger_mode (enum trigger_type) - the mode with which to

set the triggering.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: normal_trg - set based on passed argument.

trace_status - set to TRUE if normal triggering.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void set_mode(enum trigger_type trigger_mode)

{

/* variables */

/* none */







/* set the locally global normal trigger flag based on the passed mode */

normal_trg = (trigger_mode == NORMAL_TRIGGER);



/* if normal triggering - ready for trace too */

trace_status = normal_trg;





/* all done, return */

return;



}









/*

trace_rdy



Description: This function determines whether the system is ready to

start another trace. This is determined by whether or

not the system is still sampling (sampling flag) and if

it is ready for another trace (trace_status flag).



Arguments: None.

Return Value: (int) - the current trace status (TRUE if ready to do

another trace, FALSE otherwise).



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: sampling - determines if ready for another trace.

trace_status - determines if ready for another trace.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



int trace_rdy()







91

{

/* variables */

/* none */







/* ready for another trace if not sampling and trace is ready */

return (!sampling && trace_status);



}









/*

trace_done



Description: This function is called to indicate a trace has been

completed. If in normal triggering mode this means the

system is ready for another trace.



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: trace_status - may be set to TRUE.

sampling - set to FALSE.

normal_trg - determines if trace_status is changed.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void trace_done()

{

/* variables */

/* none */







/* done with a trace - if normal triggering, ready for another one */

if (normal_trg)

/* normal triggering mode - set trace_status to TRUE (ready) */

trace_status = TRUE;



/* done sampling now */

sampling = FALSE;





/* done so return */

return;



}









/*

trace_rearm



Description: This function is called to rearm the trace. It sets the

trace status to ready (TRUE). It is used to rearm the

trigger in one-shot mode.







92

Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: trace_status - set to TRUE.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void trace_rearm()

{

/* variables */

/* none */







/* rearm the trace - set status to ready (TRUE) */

trace_status = TRUE;





/* all done - return */

return;



}









/*

set_trace_size



Description: This function sets the locally global sample size to the

passed value. This is used to scale the data when

plotting a trace.



Arguments: size (int) - the trace sample size.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: sample_size - set to the passed value.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void set_trace_size(int size)

{

/* variables */

/* none */







/* set the locally global sample size */







93

sample_size = size;





/* all done, return */

return;



}









/*

set_display_scale



Description: This function sets the displayed scale type to the passed

argument. If the scale is turned on, it draws it. If it

is turned off (SCALE_NONE), it restores the saved trace

under the scale.



Arguments: scale (scale_type) - new scale type.

Return Value: None.



Input: None.

Output: Either a scale is output or the trace under the old scale

is restored.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: cur_scale - set to the passed value.

saved_axis_x - used to restore trace data under x-axis.

saved_axis_y - used to restore trace data under y-axis.



Author: Glen George

Last Modified: Mar. 17, 1997



*/



void set_display_scale(enum scale_type scale)

{

/* variables */

int i; /* loop index */







/* handle the scale type appropriately */

switch (scale) {



case SCALE_AXES: /* axes for the scale */

/* first draw them */



/* draw the x-axis */

plot_hline(X_AXIS_START, X_AXIS_POS, (X_AXIS_END -

X_AXIS_START));



/* draw the y-axis */

plot_vline(Y_AXIS_POS, Y_AXIS_START, (Y_AXIS_END -

Y_AXIS_START));



/* done with the axes */

break;



case SCALE_NONE: /* there is no scale */

/* restore trace information under old scale */



/* restore the trace under the x-axis */

for (i = X_AXIS_START; i > (i % 8))) == 0)

/* saved pixel is off */

plot_pixel(i, X_AXIS_POS, PIXEL_WHITE);

else

/* saved pixel is on */

plot_pixel(i, X_AXIS_POS, PIXEL_BLACK);

}



/* restore the trace under the y-axis */

for (i = Y_AXIS_START; i > (i % 8))) == 0)

/* saved pixel is off */

plot_pixel(Y_AXIS_POS, i, PIXEL_WHITE);

else

/* saved pixel is on */

plot_pixel(Y_AXIS_POS, i, PIXEL_BLACK);

}

}





/* now remember the scale type */

cur_scale = scale;





/* scale is taken care of, return */

return;



}









/*

clear_saved_areas



Description: This function clears all the saved areas (for saving the

trace under the axes, menus, and general areas).



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: saved_axis_x - cleared.

saved_axis_y - cleared.

saved_menu - cleared.

saved_area - cleared.



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void clear_saved_areas()

{

/* variables */

int i; /* loop indices */

int j;







/* clear x-axis and y-axis save areas */

for (i = 0; i >= 1;

/* check if moving to next byte */

if (bit_position == 0) {

/* now on high bit of next byte */

bit_position = 0x80;

bit_offset++;

}

}

}





/* restored menu area - return */

return;



}









/*

set_save_area



Description: This function sets the position and size of the area to

be saved when traces are drawn. It also clears any data

currently saved.



Arguments: pos_x (int) - x position of upper left corner of the

saved area.

pos_y (int) - y position of upper left corner of the

saved area.

size_x (int) - horizontal size of the saved area.

size_y (int) - vertical size of the saved area.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: saved_area - cleared.

saved_pos_x - set to passed value.

saved_pos_y - set to passed value.

saved_end_x - computed from passed values.

saved_end_y - computed from passed values.



Author: Glen George

Last Modified: Mar. 8, 1994



*/



void set_save_area(int pos_x, int pos_y, int size_x, int size_y)

{

/* variables */

int x; /* loop indices */

int y;







/* just setup all the locally global variables from the passed values */

saved_pos_x = pos_x;

saved_pos_y = pos_y;

saved_end_x = pos_x + size_x;

saved_end_y = pos_y + size_y;







97

/* clear the save area */

for (y = 0; y >= 1;

/* check if moving to next byte */

if (bit_position == 0) {

/* now on high bit of next byte */

bit_position = 0x80;

bit_offset++;

}

}

}





/* restored the saved area - return */

return;



}









/*

do_trace



Description: This function starts a trace. It starts the hardware

sampling data (via a function call) and sets the trace

ready flag (trace_status) to FALSE and the sampling flag

(sampling) to TRUE.



Arguments: None.

Return Value: None.



Input: None.

Output: None.



Error Handling: None.



Algorithms: None.

Data Structures: None.



Global Variables: trace_status - set to FALSE (not ready for another trace).

sampling - set to TRUE (doing a sample now).



Author: Glen George

Last Modified: Mar. 13, 1994



*/



void do_trace()

{

/* variables */

/* none */







/* start up the trace */

start_sample();



/* now not ready for another trace (currently doing one) */

trace_status = FALSE;



/* and are currently sampling data */

sampling = TRUE;





/* trace is going, return */

return;









99

}









/*

plot_trace



Description: This function plots the passed trace. The trace is

assumed to contain sample_size points of sampled data.

Any points falling within any of the save areas are also

saved by this routine. The data is also scaled to be

within the range of the entire screen (divided by

Y_SCALE_FACTOR).



Arguments: sample (unsigned char far *) - sample to plot.

Return Value: None.



Input: None.

Output: The sample is plotted on the screen.



Error Handling: None.



Algorithms: If there are more sample points than screen width the

sample is plotted with multiple points per horizontal

position.

Data Structures: None.



Global Variables: cur_scale - determines type of scale to plot.

sample_size - determines size of passed sample.

saved_axis_x - stores trace under x-axis.

saved_axis_y - stores trace under y-axis.

saved_menu - stores trace under the menu.

saved_area - stores trace under the saved area.

saved_pos_x - determines location of saved area.

saved_pos_y - determines location of saved area.

saved_end_x - determines location of saved area.

saved_end_y - determines location of saved area.



Author: Glen George, Yiyang Gong

Last Modified: 6/11/02 - added a swapbuffer function at the end of function

When a new trace is completely drawn, the buffer

switches to the other buffer, and is displayed.

The writes then happens to the other buffer (or

block of memory).



*/



void plot_trace(unsigned char far *sample)

{

/* variables */

int x = 0; /* current x position to plot */

int x_pos = (PLOT_SIZE_X / 2); /* "fine" x position for multiple point plotting */



int y; /* y position of point to plot */



int i; /* loop index */







/* first, clear the display to get rid of old plots */

clear_display();



/* clear the saved areas too */

clear_saved_areas();



/* re-display the menu (if it was on) */

refresh_menu();





/* plot the sample */







100

for (i = 0; i = X_AXIS_START) && (x > (x % 8));

if ((x == Y_AXIS_POS) && (y >= Y_AXIS_START) && (y > (y % 8));

if ((x >= MENU_UL_X) && (x = MENU_UL_Y) && (y > ((x - MENU_UL_X) %

8));

if ((x >= saved_pos_x) && (x = saved_pos_y) && (y > ((x -

saved_pos_x) % 8));



/* update x position */

x_pos += PLOT_SIZE_X;

/* check if at next horizontal position */

if (x_pos >= sample_size) {

/* at next position - update positions */

x++;

x_pos -= sample_size;

}

}





/* finally, output the scale if need be */

set_display_scale(cur_scale);



swapbuffer(); /* when the plot trace is done

swap the buffer to be displayed

and swap the display to be written

to in memory*/

/* done with plot, return */

return;



}









101

/****************************************************************************/

/* */

/* INTERFAC.H */

/* Interface Definitions */

/* Include File */

/* Digital Oscilloscope Project */

/* EE/CS 52 */

/* */

/****************************************************************************/



/*

This file contains the constants for interfacing between the C code and

the assembly code/hardware for the Digital Oscilloscope project. This is

a sample interface file to allow compilation of the .c files.





Revision History:

3/8/94 Glen George Initial revision.

3/13/94 Glen George Updated comments.

3/17/97 Glen George Added constant MAX_SAMPLE_SIZE and removed

KEY_UNUSED.

6/10/02 Yiyang Gong changed the keypad values to match the ones

written in the keypad file. Also changed the

minimum sample to one (as the timer requires a

count to 1, whereas the 0 count counts as

FFFFH + 1. Changed the maximum and minimum

sampled voltages, to fit with the MAX153 bipolar

mode. Finally, changed to pixel_white value

to the required value for the plot_pixel function

*/







#ifndef __INTERFAC_H__

#define __INTERFAC_H__





/* library include files */

/* none */



/* local include files */

/* none */





/* constants */



/* keypad constants */

#define KEY_MENU 4 /* */

#define KEY_UP 0 /* */

#define KEY_DOWN 1 /* */

#define KEY_LEFT 2 /* */

#define KEY_RIGHT 3 /* */

#define KEY_ILLEGAL 5 /* illegal key */



/* display constants */

#define SIZE_X 480 /* size in the x dimension */

#define SIZE_Y 128 /* size in the y dimension */

#define PIXEL_WHITE -2 /* pixel off - a value of FFFEH is required

by the plot_pixel function*/

#define PIXEL_BLACK 1 /* pixel on */



/* scope parameters */

#define MIN_DELAY 1 /* minimum trigger delay */

#define MAX_DELAY 65535 /* maximum trigger delay */

#define MIN_LEVEL -2500 /* minimum trigger level (in mV) */

#define MAX_LEVEL 2500 /* maximum trigger level (in mV) */



/* sampling parameters */

#define MAX_SAMPLE_SIZE 2400 /* maximum size of a sample (in samples) */



#endif







102

/****************************************************************************/

/* */

/* SCOPEDEF.H */

/* General Definitions */

/* Include File */

/* Digital Oscilloscope Project */

/* EE/CS 52 */

/* */

/****************************************************************************/



/*

This file contains the general definitions for the Digital Oscilloscope

project. This includes constant and structure definitions along with the

function declarations for the assembly language functions.





Revision History:

3/8/94 Glen George Initial revision.

3/13/94 Glen George Updated comments.

3/17/97 Glen George Removed KEYCODE_UNUSED (no longer used).

6/10/02 Yiyang Gong Added the functions swapbuffer() and

modifybuffer() to be called within the

the plot_trace function as well as

the mode_toggle function. Allows for correct

double buffering

*/







#ifndef __SCOPEDEF_H__

#define __SCOPEDEF_H__





/* library include files */

/* none */



/* local include files */

#include "interfac.h"

#include "lcdout.h"









/* constants */



/* general constants */

#define FALSE 0

#define TRUE !FALSE

#define NULL (void *) 0



/* display size (in characters) */

#define LCD_WIDTH (SIZE_X / HORIZ_SIZE)

#define LCD_HEIGHT (SIZE_Y / VERT_SIZE)









/* structures, unions, and typedefs */



/* program states */

enum status { MENU_ON, /* menu is displayed with the cursor in it */

MENU_OFF, /* menu is not displayed - no cursor */

NUM_STATES /* number of states */

};



/* key codes */

enum keycode { KEYCODE_MENU, /* */

KEYCODE_UP, /* */

KEYCODE_DOWN, /* */

KEYCODE_LEFT, /* */

KEYCODE_RIGHT, /* */







103

KEYCODE_ILLEGAL, /* other keys */

NUM_KEYCODES /* number of key codes */

};









/* function declarations */



/* keypad functions */

unsigned char key_available(void); /* key is available */

int getkey(void); /* get a key */



/* display functions */

void clear_display(void); /* clear the display */

void plot_pixel(unsigned int, unsigned int, int); /* output a pixel */

void swapbuffer(void);

void modifybuffer(void);



/* sampling parameter functions */

int set_sample_rate(long int); /* set the sample rate */

void set_trigger(int, int); /* set trigger level and slope */

void set_delay(long int); /* set the trigger delay time */



/* sampling functions */

void start_sample(void); /* capture a sample */

unsigned char far *sample_done(void); /* sample captured status */





#endif









104


Related docs
Other docs by HC111202191421
???????????? ?????????
Views: 0  |  Downloads: 0
Ward No
Views: 14  |  Downloads: 0
Verslag EDOplatform 09oktober08
Views: 1  |  Downloads: 0
LESSON 12 LUNG CAPACITY
Views: 9  |  Downloads: 0
code
Views: 0  |  Downloads: 0
PowerPoint Presentation
Views: 3  |  Downloads: 0
Beispielaufgaben Abitur 2008
Views: 19  |  Downloads: 0
Group full P&L quarter
Views: 0  |  Downloads: 0
Apresenta��o do PowerPoint
Views: 2  |  Downloads: 0
Hoja1
Views: 19  |  Downloads: 0
By registering with docstoc.com you agree to our
privacy policy

You are almost ready to download!

You are almost ready to download!