Skip to content

Instantly share code, notes, and snippets.

@vintagechips
Last active July 14, 2022 21:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vintagechips/fd5e1a3e905cf866fcf34772d0249d34 to your computer and use it in GitHub Desktop.
Save vintagechips/fd5e1a3e905cf866fcf34772d0249d34 to your computer and use it in GitHub Desktop.
HELLO, WOLD that runs in NEC V20 Emulation mode
; 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