        .ORIG x0000

; the TRAP vector table
	JUMP BAD_TRAP	; x00
	JUMP BAD_TRAP	; x01
	JUMP BAD_TRAP	; x02
	JUMP BAD_TRAP	; x03
	JUMP BAD_TRAP	; x04
	JUMP BAD_TRAP	; x05
	JUMP BAD_TRAP	; x06
	JUMP BAD_TRAP	; x07
	JUMP BAD_TRAP	; x08
	JUMP BAD_TRAP	; x09
	JUMP BAD_TRAP	; x0A
	JUMP BAD_TRAP	; x0B
	JUMP BAD_TRAP	; x0C
	JUMP BAD_TRAP	; x0D
	JUMP BAD_TRAP	; x0E
	JUMP BAD_TRAP	; x0F
	JUMP BAD_TRAP	; x10
	JUMP BAD_TRAP	; x11
	JUMP BAD_TRAP	; x12
	JUMP BAD_TRAP	; x13
	JUMP BAD_TRAP	; x14
	JUMP BAD_TRAP	; x15
	JUMP BAD_TRAP	; x16
	JUMP BAD_TRAP	; x17
	JUMP BAD_TRAP	; x18
	JUMP BAD_TRAP	; x19
	JUMP BAD_TRAP	; x1A
	JUMP BAD_TRAP	; x1B
	JUMP BAD_TRAP	; x1C
	JUMP BAD_TRAP	; x1D
	JUMP BAD_TRAP	; x1E
	JUMP BAD_TRAP	; x1F
	JUMP TRAP_GETC	; x20
	JUMP TRAP_PUTC	; x21
	JUMP TRAP_PUTS	; x22
	JUMP TRAP_EGETC	; x23
	JUMP BAD_TRAP   ; x24        
	JUMP TRAP_HALT	; x25
	JUMP TRAP_GETS	; x26
	JUMP TRAP_EGETS	; x27
	JUMP BAD_TRAP	; x28
	JUMP BAD_TRAP	; x29
	JUMP BAD_TRAP	; x2A
	JUMP BAD_TRAP	; x2B
	JUMP BAD_TRAP	; x2C
	JUMP BAD_TRAP	; x2D
	JUMP BAD_TRAP	; x2E
	JUMP BAD_TRAP	; x2F
	JUMP BAD_TRAP	; x30
	JUMP BAD_TRAP	; x31
	JUMP BAD_TRAP	; x32
	JUMP BAD_TRAP	; x33
	JUMP BAD_TRAP	; x34
	JUMP BAD_TRAP	; x35
	JUMP BAD_TRAP	; x36
	JUMP BAD_TRAP	; x37
	JUMP BAD_TRAP	; x38
	JUMP BAD_TRAP	; x39
	JUMP BAD_TRAP	; x3A
	JUMP BAD_TRAP	; x3B
	JUMP BAD_TRAP	; x3C
	JUMP BAD_TRAP	; x3D
	JUMP BAD_TRAP	; x3E
	JUMP BAD_TRAP	; x3F
	JUMP TRAP_DRAW_POINT	; x40
	JUMP TRAP_DRAW_BALL		; x41
	JUMP TRAP_DRAW_RECTANGLE	; x42
	JUMP TRAP_CHECK_POINT	; x43
	JUMP TRAP_GET_EVENT		; x44
	JUMP BAD_TRAP	; x45
	JUMP BAD_TRAP	; x46
	JUMP BAD_TRAP	; x47
	JUMP BAD_TRAP	; x48
	JUMP BAD_TRAP	; x49
	JUMP BAD_TRAP	; x4A
	JUMP BAD_TRAP	; x4B
	JUMP BAD_TRAP	; x4C
	JUMP BAD_TRAP	; x4D
	JUMP BAD_TRAP	; x4E
	JUMP BAD_TRAP	; x4F
	JUMP BAD_TRAP	; x50
	JUMP BAD_TRAP	; x51
	JUMP BAD_TRAP	; x52
	JUMP BAD_TRAP	; x53
	JUMP BAD_TRAP	; x54
	JUMP BAD_TRAP	; x55
	JUMP BAD_TRAP	; x56
	JUMP BAD_TRAP	; x57
	JUMP BAD_TRAP	; x58
	JUMP BAD_TRAP	; x59
	JUMP BAD_TRAP	; x5A
	JUMP BAD_TRAP	; x5B
	JUMP BAD_TRAP	; x5C
	JUMP BAD_TRAP	; x5D
	JUMP BAD_TRAP	; x5E
	JUMP BAD_TRAP	; x5F
	JUMP BAD_TRAP	; x60
	JUMP BAD_TRAP	; x61
	JUMP BAD_TRAP	; x62
	JUMP BAD_TRAP	; x63
	JUMP BAD_TRAP	; x64
	JUMP BAD_TRAP	; x65
	JUMP BAD_TRAP	; x66
	JUMP BAD_TRAP	; x67
	JUMP BAD_TRAP	; x68
	JUMP BAD_TRAP	; x69
	JUMP BAD_TRAP	; x6A
	JUMP BAD_TRAP	; x6B
	JUMP BAD_TRAP	; x6C
	JUMP BAD_TRAP	; x6D
	JUMP BAD_TRAP	; x6E
	JUMP BAD_TRAP	; x6F
	JUMP BAD_TRAP	; x70
	JUMP BAD_TRAP	; x71
	JUMP BAD_TRAP	; x72
	JUMP BAD_TRAP	; x73
	JUMP BAD_TRAP	; x74
	JUMP BAD_TRAP	; x75
	JUMP BAD_TRAP	; x76
	JUMP BAD_TRAP	; x77
	JUMP BAD_TRAP	; x78
	JUMP BAD_TRAP	; x79
	JUMP BAD_TRAP	; x7A
	JUMP BAD_TRAP	; x7B
	JUMP BAD_TRAP	; x7C
	JUMP BAD_TRAP	; x7D
	JUMP BAD_TRAP	; x7E
	JUMP BAD_TRAP	; x7F
	JUMP BAD_TRAP	; x80
	JUMP BAD_TRAP	; x81
	JUMP BAD_TRAP	; x82
	JUMP BAD_TRAP	; x83
	JUMP BAD_TRAP	; x84
	JUMP BAD_TRAP	; x85
	JUMP BAD_TRAP	; x86
	JUMP BAD_TRAP	; x87
	JUMP BAD_TRAP	; x88
	JUMP BAD_TRAP	; x89
	JUMP BAD_TRAP	; x8A
	JUMP BAD_TRAP	; x8B
	JUMP BAD_TRAP	; x8C
	JUMP BAD_TRAP	; x8D
	JUMP BAD_TRAP	; x8E
	JUMP BAD_TRAP	; x8F
	JUMP BAD_TRAP	; x90
	JUMP BAD_TRAP	; x91
	JUMP BAD_TRAP	; x92
	JUMP BAD_TRAP	; x93
	JUMP BAD_TRAP	; x94
	JUMP BAD_TRAP	; x95
	JUMP BAD_TRAP	; x96
	JUMP BAD_TRAP	; x97
	JUMP BAD_TRAP	; x98
	JUMP BAD_TRAP	; x99
	JUMP BAD_TRAP	; x9A
	JUMP BAD_TRAP	; x9B
	JUMP BAD_TRAP	; x9C
	JUMP BAD_TRAP	; x9D
	JUMP BAD_TRAP	; x9E
	JUMP BAD_TRAP	; x9F
	JUMP BAD_TRAP	; xA0
	JUMP BAD_TRAP	; xA1
	JUMP BAD_TRAP	; xA2
	JUMP BAD_TRAP	; xA3
	JUMP BAD_TRAP	; xA4
	JUMP BAD_TRAP	; xA5
	JUMP BAD_TRAP	; xA6
	JUMP BAD_TRAP	; xA7
	JUMP BAD_TRAP	; xA8
	JUMP BAD_TRAP	; xA9
	JUMP BAD_TRAP	; xAA
	JUMP BAD_TRAP	; xAB
	JUMP BAD_TRAP	; xAC
	JUMP BAD_TRAP	; xAD
	JUMP BAD_TRAP	; xAE
	JUMP BAD_TRAP	; xAF
	JUMP BAD_TRAP	; xB0
	JUMP BAD_TRAP	; xB1
	JUMP BAD_TRAP	; xB2
	JUMP BAD_TRAP	; xB3
	JUMP BAD_TRAP	; xB4
	JUMP BAD_TRAP	; xB5
	JUMP BAD_TRAP	; xB6
	JUMP BAD_TRAP	; xB7
	JUMP BAD_TRAP	; xB8
	JUMP BAD_TRAP	; xB9
	JUMP BAD_TRAP	; xBA
	JUMP BAD_TRAP	; xBB
	JUMP BAD_TRAP	; xBC
	JUMP BAD_TRAP	; xBD
	JUMP BAD_TRAP	; xBE
	JUMP BAD_TRAP	; xBF
	JUMP BAD_TRAP	; xC0
	JUMP BAD_TRAP	; xC1
	JUMP BAD_TRAP	; xC2
	JUMP BAD_TRAP	; xC3
	JUMP BAD_TRAP	; xC4
	JUMP BAD_TRAP	; xC5
	JUMP BAD_TRAP	; xC6
	JUMP BAD_TRAP	; xC7
	JUMP BAD_TRAP	; xC8
	JUMP BAD_TRAP	; xC9
	JUMP BAD_TRAP	; xCA
	JUMP BAD_TRAP	; xCB
	JUMP BAD_TRAP	; xCC
	JUMP BAD_TRAP	; xCD
	JUMP BAD_TRAP	; xCE
	JUMP BAD_TRAP	; xCF
	JUMP BAD_TRAP	; xD0
	JUMP BAD_TRAP	; xD1
	JUMP BAD_TRAP	; xD2
	JUMP BAD_TRAP	; xD3
	JUMP BAD_TRAP	; xD4
	JUMP BAD_TRAP	; xD5
	JUMP BAD_TRAP	; xD6
	JUMP BAD_TRAP	; xD7
	JUMP BAD_TRAP	; xD8
	JUMP BAD_TRAP	; xD9
	JUMP BAD_TRAP	; xDA
	JUMP BAD_TRAP	; xDB
	JUMP BAD_TRAP	; xDC
	JUMP BAD_TRAP	; xDD
	JUMP BAD_TRAP	; xDE
	JUMP BAD_TRAP	; xDF
	JUMP BAD_TRAP	; xE0
	JUMP BAD_TRAP	; xE1
	JUMP BAD_TRAP	; xE2
	JUMP BAD_TRAP	; xE3
	JUMP BAD_TRAP	; xE4
	JUMP BAD_TRAP	; xE5
	JUMP BAD_TRAP	; xE6
	JUMP BAD_TRAP	; xE7
	JUMP BAD_TRAP	; xE8
	JUMP BAD_TRAP	; xE9
	JUMP BAD_TRAP	; xEA
	JUMP BAD_TRAP	; xEB
	JUMP BAD_TRAP	; xEC
	JUMP BAD_TRAP	; xED
	JUMP BAD_TRAP	; xEE
	JUMP BAD_TRAP	; xEF
	JUMP BAD_TRAP	; xF0
	JUMP BAD_TRAP	; xF1
	JUMP BAD_TRAP	; xF2
	JUMP BAD_TRAP	; xF3
	JUMP BAD_TRAP	; xF4
	JUMP BAD_TRAP	; xF5
	JUMP BAD_TRAP	; xF6
	JUMP BAD_TRAP	; xF7
	JUMP BAD_TRAP	; xF8
	JUMP BAD_TRAP	; xF9
	JUMP BAD_TRAP	; xFA
	JUMP BAD_TRAP	; xFB
	JUMP BAD_TRAP	; xFC
	JUMP BAD_TRAP	; xFD
	JUMP BAD_TRAP	; xFE
	JUMP BAD_TRAP	; xFF

; the interrupt vector table
; interrupts are not currently implemented
        JUMP BAD_INT	; x00
	JUMP BAD_INT	; x01
	JUMP BAD_INT	; x02
	JUMP BAD_INT	; x03
	JUMP BAD_INT	; x04
	JUMP BAD_INT	; x05
	JUMP BAD_INT	; x06
	JUMP BAD_INT	; x07
	JUMP BAD_INT	; x08
	JUMP BAD_INT	; x09
	JUMP BAD_INT	; x0A
	JUMP BAD_INT	; x0B
	JUMP BAD_INT	; x0C
	JUMP BAD_INT	; x0D
	JUMP BAD_INT	; x0E
	JUMP BAD_INT	; x0F
	JUMP BAD_INT	; x10
	JUMP BAD_INT	; x11
	JUMP BAD_INT	; x12
	JUMP BAD_INT	; x13
	JUMP BAD_INT	; x14
	JUMP BAD_INT	; x15
	JUMP BAD_INT	; x16
	JUMP BAD_INT	; x17
	JUMP BAD_INT	; x18
	JUMP BAD_INT	; x19
	JUMP BAD_INT	; x1A
	JUMP BAD_INT	; x1B
	JUMP BAD_INT	; x1C
	JUMP BAD_INT	; x1D
	JUMP BAD_INT	; x1E
	JUMP BAD_INT	; x1F
	JUMP BAD_INT	; x20
	JUMP BAD_INT	; x21
	JUMP BAD_INT	; x22
	JUMP BAD_INT	; x23
	JUMP BAD_INT   ; x24
	JUMP BAD_INT	; x25
	JUMP BAD_INT	; x26
	JUMP BAD_INT	; x27
	JUMP BAD_INT	; x28
	JUMP BAD_INT	; x29
	JUMP BAD_INT	; x2A
	JUMP BAD_INT	; x2B
	JUMP BAD_INT	; x2C
	JUMP BAD_INT	; x2D
	JUMP BAD_INT	; x2E
	JUMP BAD_INT	; x2F
	JUMP BAD_INT	; x30
	JUMP BAD_INT	; x31
	JUMP BAD_INT	; x32
	JUMP BAD_INT	; x33
	JUMP BAD_INT	; x34
	JUMP BAD_INT	; x35
	JUMP BAD_INT	; x36
	JUMP BAD_INT	; x37
	JUMP BAD_INT	; x38
	JUMP BAD_INT	; x39
	JUMP BAD_INT	; x3A
	JUMP BAD_INT	; x3B
	JUMP BAD_INT	; x3C
	JUMP BAD_INT	; x3D
	JUMP BAD_INT	; x3E
	JUMP BAD_INT	; x3F
	JUMP BAD_INT	; x40
	JUMP BAD_INT	; x41
	JUMP BAD_INT	; x42
	JUMP BAD_INT	; x43
	JUMP BAD_INT	; x44
	JUMP BAD_INT	; x45
	JUMP BAD_INT	; x46
	JUMP BAD_INT	; x47
	JUMP BAD_INT	; x48
	JUMP BAD_INT	; x49
	JUMP BAD_INT	; x4A
	JUMP BAD_INT	; x4B
	JUMP BAD_INT	; x4C
	JUMP BAD_INT	; x4D
	JUMP BAD_INT	; x4E
	JUMP BAD_INT	; x4F
	JUMP BAD_INT	; x50
	JUMP BAD_INT	; x51
	JUMP BAD_INT	; x52
	JUMP BAD_INT	; x53
	JUMP BAD_INT	; x54
	JUMP BAD_INT	; x55
	JUMP BAD_INT	; x56
	JUMP BAD_INT	; x57
	JUMP BAD_INT	; x58
	JUMP BAD_INT	; x59
	JUMP BAD_INT	; x5A
	JUMP BAD_INT	; x5B
	JUMP BAD_INT	; x5C
	JUMP BAD_INT	; x5D
	JUMP BAD_INT	; x5E
	JUMP BAD_INT	; x5F
	JUMP BAD_INT	; x60
	JUMP BAD_INT	; x61
	JUMP BAD_INT	; x62
	JUMP BAD_INT	; x63
	JUMP BAD_INT	; x64
	JUMP BAD_INT	; x65
	JUMP BAD_INT	; x66
	JUMP BAD_INT	; x67
	JUMP BAD_INT	; x68
	JUMP BAD_INT	; x69
	JUMP BAD_INT	; x6A
	JUMP BAD_INT	; x6B
	JUMP BAD_INT	; x6C
	JUMP BAD_INT	; x6D
	JUMP BAD_INT	; x6E
	JUMP BAD_INT	; x6F
	JUMP BAD_INT	; x70
	JUMP BAD_INT	; x71
	JUMP BAD_INT	; x72
	JUMP BAD_INT	; x73
	JUMP BAD_INT	; x74
	JUMP BAD_INT	; x75
	JUMP BAD_INT	; x76
	JUMP BAD_INT	; x77
	JUMP BAD_INT	; x78
	JUMP BAD_INT	; x79
	JUMP BAD_INT	; x7A
	JUMP BAD_INT	; x7B
	JUMP BAD_INT	; x7C
	JUMP BAD_INT	; x7D
	JUMP BAD_INT	; x7E
	JUMP BAD_INT	; x7F
	JUMP BAD_INT	; x80
	JUMP BAD_INT	; x81
	JUMP BAD_INT	; x82
	JUMP BAD_INT	; x83
	JUMP BAD_INT	; x84
	JUMP BAD_INT	; x85
	JUMP BAD_INT	; x86
	JUMP BAD_INT	; x87
	JUMP BAD_INT	; x88
	JUMP BAD_INT	; x89
	JUMP BAD_INT	; x8A
	JUMP BAD_INT	; x8B
	JUMP BAD_INT	; x8C
	JUMP BAD_INT	; x8D
	JUMP BAD_INT	; x8E
	JUMP BAD_INT	; x8F
	JUMP BAD_INT	; x90
	JUMP BAD_INT	; x91
	JUMP BAD_INT	; x92
	JUMP BAD_INT	; x93
	JUMP BAD_INT	; x94
	JUMP BAD_INT	; x95
	JUMP BAD_INT	; x96
	JUMP BAD_INT	; x97
	JUMP BAD_INT	; x98
	JUMP BAD_INT	; x99
	JUMP BAD_INT	; x9A
	JUMP BAD_INT	; x9B
	JUMP BAD_INT	; x9C
	JUMP BAD_INT	; x9D
	JUMP BAD_INT	; x9E
	JUMP BAD_INT	; x9F
	JUMP BAD_INT	; xA0
	JUMP BAD_INT	; xA1
	JUMP BAD_INT	; xA2
	JUMP BAD_INT	; xA3
	JUMP BAD_INT	; xA4
	JUMP BAD_INT	; xA5
	JUMP BAD_INT	; xA6
	JUMP BAD_INT	; xA7
	JUMP BAD_INT	; xA8
	JUMP BAD_INT	; xA9
	JUMP BAD_INT	; xAA
	JUMP BAD_INT	; xAB
	JUMP BAD_INT	; xAC
	JUMP BAD_INT	; xAD
	JUMP BAD_INT	; xAE
	JUMP BAD_INT	; xAF
	JUMP BAD_INT	; xB0
	JUMP BAD_INT	; xB1
	JUMP BAD_INT	; xB2
	JUMP BAD_INT	; xB3
	JUMP BAD_INT	; xB4
	JUMP BAD_INT	; xB5
	JUMP BAD_INT	; xB6
	JUMP BAD_INT	; xB7
	JUMP BAD_INT	; xB8
	JUMP BAD_INT	; xB9
	JUMP BAD_INT	; xBA
	JUMP BAD_INT	; xBB
	JUMP BAD_INT	; xBC
	JUMP BAD_INT	; xBD
	JUMP BAD_INT	; xBE
	JUMP BAD_INT	; xBF
	JUMP BAD_INT	; xC0
	JUMP BAD_INT	; xC1
	JUMP BAD_INT	; xC2
	JUMP BAD_INT	; xC3
	JUMP BAD_INT	; xC4
	JUMP BAD_INT	; xC5
	JUMP BAD_INT	; xC6
	JUMP BAD_INT	; xC7
	JUMP BAD_INT	; xC8
	JUMP BAD_INT	; xC9
	JUMP BAD_INT	; xCA
	JUMP BAD_INT	; xCB
	JUMP BAD_INT	; xCC
	JUMP BAD_INT	; xCD
	JUMP BAD_INT	; xCE
	JUMP BAD_INT	; xCF
	JUMP BAD_INT	; xD0
	JUMP BAD_INT	; xD1
	JUMP BAD_INT	; xD2
	JUMP BAD_INT	; xD3
	JUMP BAD_INT	; xD4
	JUMP BAD_INT	; xD5
	JUMP BAD_INT	; xD6
	JUMP BAD_INT	; xD7
	JUMP BAD_INT	; xD8
	JUMP BAD_INT	; xD9
	JUMP BAD_INT	; xDA
	JUMP BAD_INT	; xDB
	JUMP BAD_INT	; xDC
	JUMP BAD_INT	; xDD
	JUMP BAD_INT	; xDE
	JUMP BAD_INT	; xDF
	JUMP BAD_INT	; xE0
	JUMP BAD_INT	; xE1
	JUMP BAD_INT	; xE2
	JUMP BAD_INT	; xE3
	JUMP BAD_INT	; xE4
	JUMP BAD_INT	; xE5
	JUMP BAD_INT	; xE6
	JUMP BAD_INT	; xE7
	JUMP BAD_INT	; xE8
	JUMP BAD_INT	; xE9
	JUMP BAD_INT	; xEA
	JUMP BAD_INT	; xEB
	JUMP BAD_INT	; xEC
	JUMP BAD_INT	; xED
	JUMP BAD_INT	; xEE
	JUMP BAD_INT	; xEF
	JUMP BAD_INT	; xF0
	JUMP BAD_INT	; xF1
	JUMP BAD_INT	; xF2
	JUMP BAD_INT	; xF3
	JUMP BAD_INT	; xF4
	JUMP BAD_INT	; xF5
	JUMP BAD_INT	; xF6
	JUMP BAD_INT	; xF7
	JUMP BAD_INT	; xF8
	JUMP BAD_INT	; xF9
	JUMP BAD_INT	; xFA
	JUMP BAD_INT	; xFB
	JUMP BAD_INT	; xFC
	JUMP BAD_INT	; xFD
	JUMP BAD_INT	; xFE
	JUMP BAD_INT	; xFF


;;; OS_START - operating system entry point (always starts at x0200)
OS_START
	;; set MPR
	LD R0, MPR_INIT
	LD R1, OS_MPR	
	STR R0, R1, 0

	;; set timer interval
	LD R0, TIM_INIT
	LD R1, OS_TIR	
	STR R0, R1, 0

	;; set user stack
	LD R6, USER_STACK

	;; start running user code (clear Privilege bit w/ JMPT)
	LD R7, USER_CODE_ADDR
	JUMPR	R7

OS_KBSR	.FILL xFE00		; keyboard status register
OS_KBDR	.FILL xFE02		; keyboard data register
OS_DSR	.FILL xFE04		; display status register
OS_DDR	.FILL xFE06		; display data register
OS_TSR	.FILL xFE08		; timer register
OS_TIR  .FILL xFE0A             ; timer interval register
OS_MPR	.FILL xFE12		; memory protection register
OS_MCR	.FILL xFFFE		; machine control register

USER_STACK	.FILL xBFFF
OS_STACK	.FILL x2FFF
	                	
MASK_HI         .FILL x7FFF
LOW_8_BITS      .FILL x00FF
TIM_INIT        .FILL #40
;MPR_INIT	.FILL xFFFF	; user can access everything
MPR_INIT	.FILL x0FF8	; user can access x3000 to xbfff
USER_CODE_ADDR	.FILL x3000	; user code starts at x3000
        

	
;; System Register Save Locations

OS_SAVE_R6      .BLKW 1
OS_SAVE_R7      .BLKW 1

;; TRAP wrappers
TRAP_GETC
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_GETC
	LD R6, OS_SAVE_R6
	LD R7, OS_SAVE_R7
	RTT R7

TRAP_PUTC
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_PUTC
	LD R7, OS_SAVE_R7
	LD R6, OS_SAVE_R6
	RTT R7
                
TRAP_PUTS
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_PUTS
	LD R7, OS_SAVE_R7
	LD R6, OS_SAVE_R6
	RTT R7

TRAP_EGETC
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_EGETC
	LD R7, OS_SAVE_R7
	LD R6, OS_SAVE_R6
	RTT R7

TRAP_GETS
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_GETS
	LD R7, OS_SAVE_R7
	LD R6, OS_SAVE_R6
	RTT R7

TRAP_EGETS
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_EGETS
	LD R7, OS_SAVE_R7
	LD R6, OS_SAVE_R6
	RTT R7
					
TRAP_GET_EVENT
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_GET_EVENT
	LD R6, OS_SAVE_R6
	LD R7, OS_SAVE_R7
	RTT R7

TRAP_DRAW_POINT
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_DRAW_POINT
	LD R6, OS_SAVE_R6
	LD R7, OS_SAVE_R7
	RTT R7

TRAP_DRAW_BALL
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_DRAW_BALL
	LD R6, OS_SAVE_R6
	LD R7, OS_SAVE_R7
	RTT R7
	
TRAP_DRAW_RECTANGLE
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_DRAW_RECTANGLE
	LD R6, OS_SAVE_R6
	LD R7, OS_SAVE_R7
	RTT R7

TRAP_CHECK_POINT
	ST R6, OS_SAVE_R6
	ST R7, OS_SAVE_R7
	LD R6, OS_STACK
	JSR OS_CHECK_POINT
	LD R6, OS_SAVE_R6
	LD R7, OS_SAVE_R7
	RTT R7
	
;;; GETC - Read a single character of input from keyboard device into R0
;;; OS_GETC - OS routine (can be called by other OS routines)
;;; TRAP_GETC - TRAP wrapper
OS_GETC
	LD R0, OS_KBSR		; wait for a keystroke
	LDR R0, R0, 0
	BRzp R0, OS_GETC
	LD R0, OS_KBDR		; read it and return
	LDR R0, R0, 0
	JUMPR R7


;;; PUTC - Write the character in R0 to the console.
;;; OS_PUTC - OS routine (can be called from other OS routines)
;;; TRAP_PUTC - TRAP wrapper
	
OS_PUTC
	INC R6, #-1
	STR R1, R6, #0		; save R1
OS_PUTC_WAIT
	LD R1, OS_DSR		; wait for the display to be ready
	LDR R1, R1, 0
	BRzp R1, OS_PUTC_WAIT

	LD R1, OS_DDR
	STR R0, R1, 0		; write the character and return

	LDR R1,	R6, #0		; restore R1
	INC R6, #1
	JUMPR R7

;;; PUTS - Write a NUL-terminated string of characters to the console,
;;; starting from the address in R0.
;;; OS_PUTS - OS routine (can be called from other OS routines)
;;; TRAP_PUTS - TRAP wrapper
	
OS_PUTS
	INC R6, #-3
	STR R0, R6, #0
	STR R1, R6, #1
	STR R7, R6, #2
	AND R1, R0, R0		; move string pointer (R0) into R1
OS_PUTS_LOOP
	LDR R0, R1, #0		; write characters in string using OUT
	BRz R0, OS_PUTS_DONE
	JSR OS_PUTC
	INC R1, #1
	JUMP OS_PUTS_LOOP

OS_PUTS_DONE
	LDR R0, R6, #0	; restore R0, R1, and R7
	LDR R1, R6, #1
	LDR R7, R6, #2
	INC R6, #3
	JUMPR R7

OS_EGETC_MSG	.STRINGZ "\nInput a character> "	

;;; EGETC - prompt the user for a single character input, which is stored
;;; in R0 and also echoed to the console.
;;; OS_EGETC - OS routine (can be called by other OS routines)
;;; TRAP_EGETC - TRAP wrapper
OS_EGETC
	INC R6, #-1
	STR R7, R6, #0
				;    overwrite later
	JSR OS_GETC		; read a character
	JSR OS_PUTC		; echo back to monitor
	CONST R0, #10		; write a linefeed, too
	JSR OS_PUTC

	LDR R7, R6, #0
	INC R6, #1
	JUMPR R7                  ; this doesn't work, because

;; Input key ASCII codes
LINEFEED_KEY	.FILL x000A	; linefeed (return)
		
OS_GETS
	INC R6, #-7
	STR R0, R6, #0
	STR R1, R6, #1
	STR R2, R6, #2
	STR R3, R6, #3
	STR R4, R6, #4
	STR R5, R6, #5
	STR R7, R6, #6
	
	AND R2, R0, R0		
	AND R3, R1, R1

	CONST R4, #0
OS_GETS_LOOP
	SUB R5, R3, R4		; Check for buffer overflow
	INC R5, #-1
	BRz R5, OS_GETS_DONE
	
	JSR OS_GETC		; Read character
	LD R5, LINEFEED_KEY
	SUB R5, R5, R0		; Wait for return
	BRz R5, OS_GETS_DONE
	
	ADD R5, R2, R4
	STR R0, R5, #0
	INC R4, #1
	JUMP OS_GETS_LOOP

OS_GETS_DONE
	CONST R0, #0		; Write null terminator
	ADD R5, R2, R4
	STR R0, R5, #0
	
	LDR R0, R6, #0
	LDR R1, R6, #1
	LDR R2, R6, #2
	LDR R3, R6, #3
	LDR R4, R6, #4
	LDR R5, R6, #5
	LDR R7, R6, #6
	INC R6, #7
	JUMPR R7

OS_EGETS
	INC R6, #-7
	STR R0, R6, #0
	STR R1, R6, #1
	STR R2, R6, #2
	STR R3, R6, #3
	STR R4, R6, #4
	STR R5, R6, #5
	STR R7, R6, #6
	
	AND R2, R0, R0		
	AND R3, R1, R1

	CONST R4, #0
OS_EGETS_LOOP
	SUB R5, R3, R4		; Check for buffer overflow
	INC R5, #-1
	BRz R5, OS_EGETS_DONE
	
	JSR OS_GETC		; Read character
	JSR OS_PUTC
	LD R5, LINEFEED_KEY
	SUB R5, R5, R0		; Wait for return
	BRz R5, OS_EGETS_DONE
	
	ADD R5, R2, R4
	STR R0, R5, #0
	INC R4, #1
	JUMP OS_EGETS_LOOP

OS_EGETS_DONE
	CONST R0, #0		; Write null terminator
	ADD R5, R2, R4
	STR R0, R5, #0
	
	LDR R0, R6, #0
	LDR R1, R6, #1
	LDR R2, R6, #2
	LDR R3, R6, #3
	LDR R4, R6, #4
	LDR R5, R6, #5
	LDR R7, R6, #6
	INC R6, #7

	JUMPR R7

;;; HALT - trap handler for halting machine
TRAP_HALT	
	LD R2,OS_MCR
	LDR R0, R2, 0
	LD R1,MASK_HI           ; clear run bit in MCR
	AND R0,R0,R1
	STR R0, R2, 0		; halt!
	JUMP OS_START		; restart machine

        
;;; BAD_TRAP - code to execute for undefined trap
BAD_TRAP
	JUMP TRAP_HALT		; execute HALT


;;; BAD_INT - code to execute for undefined interrupt. There won't 
;;; actually be any interrupts, so this will never actually get called.
BAD_INT	
	RTT R7

; Data Section for User Defined Traps

;; Video Memory Constants

VIDEO_MEM_BEGIN   .FILL xC000
VIDEO_ROW_SIZE    .FILL x0080

;; Input key ASCII codes
LEFT_KEY        .FILL x0061     ; Left - A
RIGHT_KEY       .FILL x0064     ; Right - D
QUIT_KEY        .FILL x0071	; Quit - Q


; ------------------------------------------------------

; Get Event Subroutine - gets the next event
OS_GET_EVENT
; Arguments: none
; Return: R5 - event

	INC R6, #-2
	STR R0, R6, #0		; save registers
	STR R1, R6, #1

	; Tight loop gets timer or key input
KEY_WAIT
	LD R0, OS_TSR
	LDR R0, R0, 0
	BRnp R0, KEY_MOVE_BALL
	LD R0,OS_KBSR
	LDR R0, R0, 0
	BRz R0, KEY_WAIT
	LD R0, OS_KBDR
	LDR R0, R0, 0

	LD R1,LEFT_KEY		; Check for left movement
	SUB R1, R0, R1
	BRz R1, KEY_MOVE_LEFT
	
	LD R1,RIGHT_KEY		; Check for right movement
	SUB R1, R0, R1
	BRz R1, KEY_MOVE_RIGHT

	LD R1,QUIT_KEY		; Check for quit
	SUB R1,R0,R1
	BRz R1, KEY_MOVE_QUIT

	JUMP KEY_WAIT

KEY_MOVE_BALL
	CONST R5, #0
	JUMP RETURN_EVENT		; Return value = 0 (timer, move ball)
KEY_MOVE_LEFT
	CONST R5, #1
	JUMP RETURN_EVENT		; Return value = 1 (left)
KEY_MOVE_RIGHT
	CONST R5, #2
	JUMP RETURN_EVENT		; Return value = 2 (right)
KEY_MOVE_QUIT
	CONST R5, #-1
	JUMP RETURN_EVENT
RETURN_EVENT

	LDR R1, R6, #1		; restore all registers except R5
	LDR R0, R6, #0

        JUMPR R7

; ------------------------------------------------------

; Draw Point subroutine - quickly draws a point
OS_DRAW_POINT
; Arguments: R0 - row, R1 - col, R2 - color
; Return: None
	INC R6, #-2
	STR R0, R6, #0		; save registers
	STR R3, R6, #1

	LD R3, VIDEO_ROW_SIZE
	MUL R0, R0, R3		; R0 = curr row * row size
	LD R3, VIDEO_MEM_BEGIN
	ADD R0, R0, R3		; R0 = vid_mem_begin + curr row * row size
	ADD R0, R0, R1		; R0 = vid_mem_begin + curr row * row size + curr col
	
	STR R2, R0, #0		; mem[R0] = R2

	LDR R3, R6, #1	; restore registers
	LDR R0, R6, #0
	INC R6, #2

        JUMPR R7

; ------------------------------------------------------

; Draw Ball subroutine - quickly draws the ball
OS_DRAW_BALL
; Arguments: R0 - row, R1 - col, R2 - color
; Return: None
	INC R6, #-2
	STR R0, R6, #0		; save registers
	STR R3, R6, #1
	
	LD R3, VIDEO_ROW_SIZE
	MUL R0, R0, R3		; R0 = curr row * row size
	LD R3, VIDEO_MEM_BEGIN
	ADD R0, R0, R3		; R0 = vid_mem_begin + curr row * row size
	ADD R0, R0, R1		; R0 = vid_mem_begin + curr row * row size + curr col
	
	STR R2, R0, #0		; mem[R0] = R2
	STR R2, R0, #1		; mem[R0+1] = R2
	ADD R0, R0, R3
	STR R2, R0, #0		; mem[R0] = R2
	STR R2, R0, #1		; mem[R0+1] = R2
	
	LDR R3, R6, #1	; restore registers
	LDR R0, R6, #0
	INC R6, #2

        JUMPR R7

; ------------------------------------------------------

; Draw Rectangle subroutine - draws a rectangle into video memory
OS_DRAW_RECTANGLE
; Arguments: R0 - row, R1 - col, R2 - height, R3 - width, R4 - color
; Return: void
	INC R6, #-5
	STR R0, R6, #0
	STR R1, R6, #1
	STR R2, R6, #2
	STR R3, R6, #3
	STR R5, R6, #4

	LD R5,VIDEO_ROW_SIZE	; R5 = row size
	MUL R0,R0,R5
	ADD R0,R0,R1		
	LD R1,VIDEO_MEM_BEGIN
	ADD R0,R0,R1		; R0 = beginning address in video memory

				; R3 = curr col (relative to beginning addr)
				; R2 = curr row (relative to beginning addr)
DB_OUTER_LOOP
	INC R2, #-1		; begin outer loop iteration
	LDR R3, R6, #3
DB_INNER_LOOP
	INC R3, #-1		; begin inner loop iteration

	; Loop body - Store color to video

	MUL R1,R2,R5	; R1 = height * row size
	ADD R1,R1,R0	; R1 = begin_addr + curr row * row size
	ADD R1,R1,R3	; R1 = begin_addr + curr row * row size + curr col
	
	STR R4,R1,#0	; mem[R1] = color

	; End loop body

	BRp R3, DB_INNER_LOOP

	BRp R2, DB_OUTER_LOOP

	LDR R5, R6, #4	; restore all registers
	LDR R3, R6, #3
	LDR R2, R6, #2
	LDR R1, R6, #1
	LDR R0, R6, #0
	INC R6, #5
	JUMPR R7

; ------------------------------------------------------

; Check Point subroutine - checks the color of a point in video memory
OS_CHECK_POINT
; Arguments: R0 - row, R1 - col
; Return: R5 - color
	INC R6, #-2
	STR R0, R6, #0
	STR R2, R6, #1

	LD R2, VIDEO_ROW_SIZE
	MUL R0, R0, R2		; R0 = curr row * row size
	LD R2, VIDEO_MEM_BEGIN
	ADD R0, R0, R2		; R0 = vid_mem_begin + curr row * row size
	ADD R0, R0, R1		; R0 = vid_mem_begin + curr row * row size + curr col
	LDR R5, R0, #0		; R5 = mem[R0]

	LDR R2, R6, #1
	LDR R0, R6, #0
	INC R6, #2
	JUMPR R7

