-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpix.a18
261 lines (256 loc) · 6.12 KB
/
pix.a18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
; -------------------------------------------------------------------
; *** pix: a simple image displayer for the 1861 Pixie chip
; ***
; *** Build #
; *** 1: Initial version
; *** 2: Use local stack and 'dec r2' after ret/dis to keep r2
; *** inbounds (ret/dis increment r2)
; *******************************************************************
; *** This software is copyleft 2021 by Wayne Hortensius ***
; *** All wrongs reserved. ***
; *******************************************************************
; *** Assembled with my modified version of the A18 assembler ***
; *** originally from https://github.com/carangil/A18: ***
; *** New & alternately named pseudo-ops: #else, #endif, #if, ***
; *** .echo, .error, .eject, .page, .title, call, dc, eject, ***
; *** endif, include, mov, pop, popd, push, pushd, retn, title ***
; *** Geany compatible error messages ***
; *******************************************************************
;
incl "bios.inc"
incl "kernel.inc"
;
OrgAddr equ 2000h
;
org OrgAddr-6
dw OrgAddr
dw endrom-OrgAddr
dw OrgAddr
org OrgAddr
Start: br Main
;
Date: db 80h+7 ; Month: July
db 21 ; Day 21
dw 2021 ; year = 2021
;
Build: dw 2 ; build number
db '@Copyleft 2021 Wayne Hortensius',0
;
cr equ 13
lf equ 10
tab equ 9
;
; Register usage
; R0: DMA address
; R!: interrupt address
; R2-R6: Elf/OS
; R7:
; R8:
; R9:
; RA:
; RB:
; RC:
; RD:
; RE: Elf/OS
; RF:
;
Main: load rf,saveStack ; save Elf/OS's stack
ghi r2
str rf
inc rf
glo r2
str rf
load r2,localStack ; use our own stack
;
lda ra ; ra -> command tail
smi ' ' ; skip over spaces to find
lbz Main ; filename argument
dec ra
ghi ra ; temp copy of argument address in rf
phi rf
glo ra
plo rf
FindTerminator:
lda rf ; look for first non printable char
smi ' '+1 ; (i.e. end of command tail)
lbdf FindTerminator
dec rf
ldi 0 ; terminate command tail with NUL
str rf
ghi ra ; ra -> start of filename argument
phi rf ; copy ra to rf
glo ra
plo rf
ldn rf ; any argument?
lbnz OpenImg ; yep, try opening it as a file
call f_inmsg ; otherwise display usage message
db 'Usage: pix imagefile',cr,lf,0
lbr Exit ; return to Elf/OS
;
OpenImg:
load rd,ImgFildes ; image file descriptor
ldi 0 ; (no create, no truncate, no append) flags
plo r7
call O_OPEN ; attempt to open file
lbnf ImgOpened ; DF=0, file was opened
call f_inmsg
db 'File not found',cr,lf,0
lbr Exit ; return to Elf/OS
;
ImgOpened:
load rc,512
load rf,ImgBuff
load rd,ImgFildes
call O_READ ; read the image file
lbdf ReadError ; DF=1, read error
glo rc ; check file size read
lbnz SizeError
ghi rc
smi 1
lbz Display32
smi 1
lbz Display64
SizeError:
call f_inmsg
db 'Unknown image resolution',cr,lf,0
lbr CloseFileAndExit
;
ReadError:
call f_inmsg
db 'Error reading image file',cr,lf,0
lbr CloseFileAndExit
;
Display32:
load r1,interrupt32 ; Set up interrupt register
ldi 023H ; Value for x=2; p=3
str r2 ; Save for return instruction
ret ; Keep x=2; p=3 and enable interrupts
dec r2
lbr Display ; go to main routine and wait for interrupt
Display64:
load r1,interrupt64 ; Set up interrupt register
ldi 023H ; Value for x=2; p=3
str r2 ; Save for return instruction
ret ; Keep x=2; p=3 and enable interrupts
dec r2
Display:
inp 1 ; Turn on Video
call f_inmsg
db 'Press any key to exit...',0
ghi re
ani 0feh ; turn echo off
phi re
Wait: call O_READKEY ; wait for Input pressed to exit
ldi 23H ; value for x=2, p=3
str r2 ; store on stack for disable instruction
dis ; x=2, p=3 and disable interrupts
dec r2
out 1 ; turn off Video, increments stack
dec r2 ; put stack pointer back to original
out 1 ; and once more for Gaston's Teensy
dec r2 ; 1861!
call f_inmsg
db cr,lf,0
ghi re
ori 001h ; turn echo back on
phi re
CloseFileAndExit:
load rf,ImgFildes
call O_CLOSE ; close the image file
Exit: load rf,saveStack ; restore Elf/OS's stack
lda rf
phi r2
ldn rf
plo r2
retn ; return to Elf/OS
;
return32:
ldxa ; restore D,
ret ; return point X, P back to original locations
interrupt32:
dec r2 ; move stack pointer
sav ; save T register
dec r2 ; move stack pointer
str r2 ; Store D onto stack
nop ; 3 nops = 9 cycles to make interrupt
nop ; routine exactly the 29 instruction cycles
nop ; required for 1861 timing
ldi high ImgBuff ; point dma register at code page
phi r0 ;
ldi low ImgBuff ; point dma register at code page
plo r0
refresh32:
glo r0 ; D = r0.0
sex r2 ; X = 2
; <----- 8 DMA cycles occur here (R0+8)
sex r2 ; there is time for exactly 6 instruction cycles
dec r0 ; utilized here by 3 two-cycle instructions
plo r0 ; in between dma requests
; <----- 8 DMA cycles occur here (R0+8)
sex r2
dec r0
plo r0
; <----- 8 DMA cycles occur here (R0+8)
sex r2
dec r0
plo r0
; <----- 8 DMA cycles occur here (R0+8)
bn1 refresh32 ; go to refresh if EF1 false
br return32 ; return if EF1 true (end of frame)
;
return64:
ldxa ; restore D,
ret ; return point X, P back to original locations
interrupt64:
dec r2 ; move stack pointer
sav ; save T register
dec r2 ; move stack pointer
str r2 ; Store D onto stack
nop ; 3 nops = 9 cycles to make interrupt
nop ; routine exactly the 29 instruction cycles
nop ; required for 1861 timing
ldi high ImgBuff ; point dma register at code page
phi r0 ;
ldi low ImgBuff ; point dma register at code page
plo r0
refresh64:
glo r0 ; D = r0.0
sex r2 ; X = 2
; <----- 8 DMA cycles occur here (R0+8)
sex r2 ; there is time for exactly 6 instruction cycles
dec r0 ; utilized here by 3 two-cycle instructions
plo r0 ; in between dma requests
; <----- 8 DMA cycles occur here (R0+8)
sex r2
sex r2
glo r0
; <----- 8 DMA cycles occur here (R0+10)
sex r2
dec r0
plo r0
; <----- 8 DMA cycles occur here (R0+10)
bn1 refresh64 ; go to refresh if EF1 false
br return64 ; return if EF1 true (end of frame)
;
ImgFildes:
db 0,0,0,0
dw ImgDTA
db 0,0
db 0
db 0,0,0,0
dw 0,0
db 0,0,0,0
;
endrom equ $
;
ds 80
localStack:
ds 1
saveStack:
ds 2
;
page
ImgBuff: ds 512
;
ImgDTA: ds 512
end