Last active
July 14, 2022 21:12
-
-
Save vintagechips/fd5e1a3e905cf866fcf34772d0249d34 to your computer and use it in GitHub Desktop.
HELLO, WOLD that runs in NEC V20 Emulation mode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; SBCV20 terminal test program | |
; Assembler: asm86.com/asm86.cmd | |
; | |
MEM equ 0000h ;Memory top | |
ROM equ 8000h ;Rom top | |
STACK equ 8000h ;Stack top | |
REGAD equ 00h ;8251 data register | |
REGAC equ 01h ;8251 control register | |
RTSHIG equ 17h ;RTS high | |
RTSLOW equ 37h ;RTS low | |
; | |
BUFSIZ equ 128 ;Buffer size(2^n, max128) | |
FULSIZ equ BUFSIZ*14/16 ;Buffer almost full | |
; | |
dseg MEM | |
org 0000h | |
; | |
; Interrupt vector | |
DEVERR rw 2 ;Devide error | |
BRKFLG rw 2 ;Break flag | |
NMIREQ rw 2 ;Non maskable interrupt | |
BR3INS rw 2 ;BRK3 instruction | |
BRVINS rw 2 ;BRKV instruction | |
CHKINS rw 2 ;CHKIND instruction | |
org 0400h-20 | |
VGETCH rw 2 ;CALLN 251 | |
VKBHIT rw 2 ;CALLN 252 | |
VPUTCH rw 2 ;CALLN 253 | |
VBRKEM rw 2 ;BRKEM 254 | |
INTREQ rw 2 ;External interrupt | |
; | |
; Receive buffer | |
RECBUF rb BUFSIZ | |
RBFRDP rw 1 | |
RBFWTP rw 1 | |
RBFCNT rb 1 | |
; | |
cseg MEM | |
org ROM | |
; | |
; 8251 -> buffer by interrupt | |
; | |
intsr: push ax ;Save ax | |
push bx ;Save bx | |
in al,REGAD ;Get char | |
mov ah,al ;Save it | |
; | |
mov al,RBFCNT ;Get count of chars | |
cmp al,BUFSIZ ;Buffer full? | |
jz isext ;If yes, ignore | |
inc al ;Count up | |
mov RBFCNT,al ;Update | |
cmp al,FULSIZ ;Buffer almost full? | |
jnz isst1 ;If no, skip flow control | |
mov al,RTSHIG ;RTS control | |
out REGAC,al ;Out it | |
; | |
isst1: mov bx,RBFWTP ;Get write point | |
mov al,ah ;Restore char | |
mov [bx],al ;Write char into buffer | |
; | |
inc bl ;Next write point | |
and bl,BUFSIZ-1 ;Wrap | |
mov RBFWTP,bx ;Update | |
; | |
isext: pop bx ;Restore bx | |
pop ax ;Restore ax | |
sti ;Enable interrupt | |
iret | |
; | |
; buffer -> al | |
getch: push bx ;Save bx | |
; | |
gcst1: mov al,RBFCNT ;Get count of chars | |
cmp al,0 ;Buffer enpty? | |
jz gcst1 ;If yes, wait | |
cli ;Disable interrupt | |
; | |
mov al,RBFCNT ;Critical timing measures | |
cmp al,FULSIZ ;Need flow control? | |
jnz gcst2 ;If no, skip flow control | |
mov ah,al ;Save char | |
mov al,RTSLOW ;RTS control | |
out REGAC,al ;Out it | |
mov al,ah ;Restore char | |
gcst2: dec al ;Count down | |
mov RBFCNT,al ;Update | |
; | |
mov bx,RBFRDP ;Get read point | |
mov al,[bx] ;Read char from buffer | |
; | |
inc bl ;Next read point | |
and bl,BUFSIZ-1 ;Wrap | |
mov RBFRDP,bx ;Update | |
; | |
pop bx ;Restore bx | |
sti ;Enable interrupt | |
ret | |
; | |
; al -> 8251 | |
putch: push ax ;Save char | |
; | |
pcst1: in al,REGAC ;Get status | |
and al,01h ;check TxBUF enpty | |
jz pcst1 ;wait for empty | |
; | |
pop ax ;Restore char | |
out REGAD,al ;Out it | |
ret | |
; | |
; put string | |
puts: cld ;set DF for SI increment | |
ptst1: lodsb ;get data to AL and SI++ | |
cmp al,00h ;check tail | |
jz ptext ;if tail, return | |
call putch ;display a charactor | |
jmp ptst1 ;loop until tail | |
ptext: ret | |
; | |
; message | |
ckcpu db 13,10,'PROCESSOR: ',0 | |
nec db 'NEC V20(uPD70108)',13,10,0 | |
intel db 'Intel 8088',13,10,0 | |
; | |
; CALLN wrapping | |
ngetch: call getch | |
iret | |
nkbhit: mov al,RBFCNT ;Get count of chars | |
iret | |
nputch: call putch | |
iret | |
; | |
; start | |
start: mov ax,cs ;set com model | |
mov ds,ax | |
mov es,ax | |
mov ss,ax | |
mov sp,STACK ;set stack | |
; | |
mov VGETCH,offset ngetch | |
mov VGETCH+2,ax | |
mov VKBHIT,offset nkbhit | |
mov VKBHIT+2,ax | |
mov VPUTCH,offset nputch | |
mov VPUTCH+2,ax | |
mov VBRKEM,offset emu80 | |
mov VBRKEM+2,ax | |
mov INTREQ,offset intsr | |
mov INTREQ+2,ax | |
; | |
; 8251 setup | |
mov dx,REGAC | |
mov al,00h ;Default mode or no operation | |
out dx,al ;Try command | |
out dx,al ;Try command | |
out dx,al ;Try command | |
mov al,40h ;reset | |
out dx,al ;Delay | |
mov CX,16 ;Delay | |
loop $ ;Delay | |
mov al,4eh ;mode | |
out dx,al ;Out it | |
mov al,37h ;command | |
out dx,al ;Out it | |
; | |
; Buffer initialize | |
xor al,al ;Clear al | |
mov RBFCNT,al ;Set count of chars | |
mov ax,offset RECBUF ;Get buffer top | |
mov RBFRDP,ax ;Set read point | |
mov RBFWTP,ax ;Set write point | |
; | |
sti ;Enable interrupt | |
; | |
; display CPU | |
mov si,offset ckcpu ;set message top | |
call puts ;display message | |
; | |
; Check CPU | |
mov ax,0101h | |
db 0d5h,10h ;aad 10h | |
cmp al,0Bh ;NEC V20 ignores the argument | |
je isv20 | |
mov si,offset intel | |
isV20: call puts | |
; | |
; Emulation sequence | |
db 0fh,0ffh ;BRKEM | |
db offset VBRKEM/4 ;Vector number | |
; | |
emu80: | |
db 21h ;LXI | |
dw offset hello | |
string: | |
db 7Eh ;MOV A,M | |
db 0FEh,0 ;CPI 0 | |
db 0CAh ;JZ | |
dw offset loop | |
db 0EDh,0EDh,0FDh ;CALLN 253(putch) | |
db 23h ;INX H | |
db 0C3h ;JMP | |
dw offset string | |
loop: | |
db 0EDh,0EDh,0FBh ;CALLN 251(getch) | |
db 0EDh,0EDh,0FDh ;CALLN 253(putch) | |
db 0C3h ;JMP | |
dw offset string | |
; | |
hello: ;HELLO, WORLD,CR,LF,0 | |
db 48h,45h,4Ch,4Ch | |
db 4Fh,2Ch,20h,57h,4Fh,52h | |
db 4Ch,44h,0Dh,0Ah,00 | |
; | |
; reset | |
org 0fff0h | |
db 0eah ;jmp | |
dw start ;offset | |
dw 0000h ;segment | |
; | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment