Код:
.mcall .ttyout .exit
.enabl LC
.list meb
VSIOLD: .word 0
VSYCNT: .word 0
PPCOMM: .word 0
; //////////////////////////////////////////////////////////////////////////////
; // START
; //////////////////////////////////////////////////////////////////////////////
START:
; run PPU code
inc PPCOMM ; ask PPU for 'phase 1 ready'
mov #PPUSTA, R4 ; run PPU code
mov #<PPUEND-PPUSTA/2>, R5
call PPRUN
tst PPCOMM ; wait for 'ppu phase 1 ready'
bne .-4
; set vsync interrupt for counting
mov @#100, VSIOLD
mov #VSYNCI, @#100
; ask PPU run test and wait for it to finish
inc PPCOMM
clr VSYCNT
tst PPCOMM
bne .-4
; restore vsync interrupt
mov VSIOLD, @#100
; clear PPU RAM
call PPRELE ; release PPU memory
; print results
mov VSYCNT, R0
call P00000
.exit
; //////////////////////////////////////////////////////////////////////////////
; 50Hz interrupt
VSYNCI: inc VSYCNT
rti
P00000: mov #5, R3
PrintP: mov #Pri000+5, R5
1$: mov R0, R1
clr R0
div #10., R0
add #'0, R1
movb R1, -(R5)
sob R3, 1$
PriOut: movb (R5)+, R0
beq 3$
.ttyout
br PriOut
3$: return
Pri000: .ASCIZ /00000/
.EVEN
; //////////////////////////////////////////////////////////////////////////////
; // CPU -> PPU exchange
; //////////////////////////////////////////////////////////////////////////////
; PPU message
;
PPMSG: .WORD PPARR ; address of beginning of array
.WORD 177777 ; end of transmission
; PPU data exchange array
;
PPARR: .BYTE 0 ; return value (0 - OK)
PPCMD: .BYTE 0 ; command
.WORD 32 ; device type (32 - PPU mem)
PPAPP: .WORD 0 ; address for PPU
PPACP: .WORD 0 ; address for CPU
PPLEN: .WORD 0 ; length in words
; send command to PPU with exch array
PPSEN: mov R0, -(SP)
mov R1, -(SP)
mov #PPMSG, R0 ; array address
mov #5, R1 ; bytes to send+1 (sending from @#PP_MSG)
br 1$
2$: movb (R0)+, @#176676
1$: tstb @#176674 ; test if we are ready to send
bpl 1$ ; cycle if >= 0 (not set last bit in byte)
sob R1, 2$
mov (SP)+, R1
mov (SP)+, R0
return
; send and start PPU code
; R4 - start addr in CPU
; R5 - length / 2
PPRUN: movb #1, PPCMD ; 1 - allocate memory
mov R5, PPLEN
call PPSEN
tstb PPARR ; test if allocate success
beq 1$ ; 0 - OK
; .print #MSG010
.exit ; fatal error - out of memory in PPU
1$: movb #20, PPCMD ; 20 - write to PPU mem
mov R5, PPLEN
mov R4, PPACP
call PPSEN
movb #30, PPCMD ; 30 - run
call PPSEN
return
; release PPU memory in case of something..
PPRELE: movb #2, PPCMD ; 2 - release memory
call PPSEN
return
; //////////////////////////////////////////////////////////////////////////////
; // PPU code
; //////////////////////////////////////////////////////////////////////////////
PPUSTA:
; clear current command (phase 1 ready, code loaded)
mov #PPCOMM/2, @#177010
clr @#177014
; wait for 'start test'
2$: mov #PPCOMM/2, @#177010
tst @#177014
beq 2$
mov #200., R4
10$: mov PC, R0
add #PPBUF1-., R0
mov PC, R1
add #PPBUF2-., R1
mov #2500., R3
20$: mov (R0)+, (R1)+
sob R3, 20$
sob R4, 10$
; test ends
mov #PPCOMM/2, @#177010
clr @#177014
return
PPBUF1: .blkw 2500.
PPBUF2: .blkw 2500.
; //////////////////////////////////////////////////////////////////////////////
; // END PPU CODE
; //////////////////////////////////////////////////////////////////////////////
PPUEND:
.END START